Chapter 21. The D (Define a Macro) Configuration Command

The sendmail program supports three flavors of macros: class macros (Chapter 22 on page 854) are used to represent multiple values; database-map macros (Chapter 23 on page 878) represent values stored in external files or networked maps; and defined macros represent values stored in the internal symbol table.

Defined macros also come in three flavors. The m4 compile-time macros (To Port, Tune, or Debug on page 105) are used when building the sendmail program and its companion programs. The mc configuration macros (m4 Macros by Function on page 594) are used when converting an mc file into a sendmail configuration file. In this chapter, we discuss the third approach, sendmail macros, which allow strings of text to be represented symbolically inside a sendmail configuration file.

Defined sendmail macros can be declared (given names and assigned the strings of text that will become values) at five different times:

  • When sendmail first begins to run, it preassigns strings of text to certain sendmail macros.

  • When sendmail processes its command line, macros that were declared by using the -M (Command-Line Definitions on page 786) command-line switch[301] are assigned their values.

  • When sendmail reads its configuration file, macros that were declared by using the D configuration-file command (Configuration-File Definitions on page 787) are assigned their values.

  • Many macros are assigned values internally by sendmail as mail is received and sent.

  • And macros can be given values as part of rule sets using the macro database-map type (macro on page 925).

Defined sendmail macros can be used in any configuration-file command. Generally, they are expanded (their value is used) when mail is sent or received.

Preassigned sendmail Macros

When sendmail first begins to run, it preassigns values to certain sendmail macros. The complete list of these macros is shown in Table 21-1. Each is described in detail at the end of this chapter, in Alphabetized sendmail Macros on page 798.

Table 21-1. Preassigned macros

Macro

§

Description

$b

$b on page 807

The current date in RFC822 format

${deliveryMode}

${deliveryMode} on page 820

The current delivery mode (V8.9 and later)

$j

$j on page 830

The canonical hostname

$k

$k on page 831

UUCP node name (V8.1 and later)

${load_avg}

${load_avg} on page 832

The current load average (V8.10 and later)

$m

$m on page 833

The domain name (V8.1 and later)

$n

$n on page 836

The bounced mail sender

${opMode}

${opMode} on page 839

The startup operating mode (V8.7 and later)

$v

$v on page 849

The sendmail program’s version

$w

$w on page 850

The short name of this host

All preassigned sendmail macros can be redefined in the configuration file or in the command line. The -d35.9 (-d35.9 on page 563) debugging switch (when run on a configuration file that only contains the V version) can be used to watch sendmail predefine its macros.[302]

Note that the mc configuration technique uses many more macros than are shown here (see Table 21-5 on page 796). But even with that technique this short list of macros is all that are internally defined by the sendmail program when it first starts up.

Also note that many more macros are defined while sendmail sends and receives messages, and processes its queue (see Alphabetized sendmail Macros on page 798 for a list of all macros).

Macros and the System Identity

The nature of email addresses requires that sendmail have a firm understanding of the machine on which it is running. The -d0.4 debugging switch (-d0.4 on page 542) causes sendmail to print its understanding of what the local machine is. A portion of that output displays the value of four key sendmail macros:

=  ==  ==  ==  ==  ==  = SYSTEM IDENTITY (after readcf) =  ==  ==  ==  ==  ==  =
      (short domain name) $w = here
  (canonical domain name) $j = here.our.domain
         (subdomain name) $m = our.domain
              (node name) $k = here
=  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==
==  ==  ==  ==  ==  ==  =

The short domain name (in $w; see $w on page 850) is simply the name of the local host without any domain information added as a suffix. The canonical domain name (in $j; see $j on page 830) is the fully qualified and official name of the local machine. The subdomain name (in $m; see $m on page 833) is just the domain part of the canonical name without a leading dot. And the node name (in $k; see $k on page 831) is the UUCP name of the local machine.

In addition to these macros, sendmail initializes the class $=w with a list of alternative names for the local host ($=w on page 876), and the class $=m with a list of the local domains ($=m on page 872).

Command-Line Definitions

Defined sendmail macros can also be declared when sendmail processes its command line, by using either the -M command-line switch or the M option (M on page 1118). The forms for these command-line declarations are:

-oMXtextno longer recommended
-MXtextpreferred as of V8.7

For both forms, the X is the sendmail macro name, which can be single-character or multicharacter (we discuss this soon). The text follows the name and is the value assigned to the macro.

In the first form, the -o switch tells sendmail that this is an option. The M is the name of the option. The M option causes sendmail to use the characters that follow the M as a macro definition. This form still works but might be eliminated in a future version of sendmail.

In the second form, the -M command-line switch causes sendmail to use the characters that follow the M as a macro definition. Beginning with V8.7 sendmail, this is now the preferred form.

Because these forms of definition are a part of the command line, all special characters are interpreted by the shell. Any text that contains shell wildcard or history characters should have each of those special characters prefixed with a backslash:

-MXsurprise\!me      ← /! is special for the C and bash shells

Command-line macros are defined before the configuration file is read and parsed by sendmail. Note that configuration-file macros always override command-line macros. Despite this, command-line definitions can still be useful. Preassigned macros can be given new values, and user-defined macros can be initialized in the command line.

For security reasons, only the r and s macros[303] allow sendmail to retain any special privilege. Overriding the value of any other macro from the command line causes sendmail to give up that special privilege.

Syntax of the Command-Line Macro’s Text

When a sendmail macro is declared on the command line, its text value is taken from the command line as is:

-oMXtextobsolete
-MXtext

Unlike sendmail macros declared in the configuration file (which we describe next), command-line declarations do not handle escape characters.

The whole suite of special operators available to your shell can be used to generate an appropriate text value. For example, the following assigns the name of your Usenet news server to the macro N:

-MN$NNTPSERVER

The $NNTPSERVER (if defined) holds the shell’s environment variable that contains the address of the news server as its value.

Configuration-File Definitions

When sendmail reads the configuration file, macros that are declared in that file are assigned values. The configuration-file command that declares macros begins with the letter D. There can be only one macro command per line. The form of the D macro configuration command is:

DXtext

The symbolic name of the macro (here, X) is a single-character or a multicharacter name (Macro Names on page 790):

DXtextsingle-character name X
D{XXX}textmulticharacter name XXX

The symbolic name must immediately follow the D with no intervening space. The value that is given to the macro is the text, consisting of all characters beginning with the first character following the name and including all characters up to the end of the line. Any indented lines that follow the definition are joined to that definition. When joined, the newline and indentation characters are retained. Consider the following three configuration lines:

DXsometext
        moretext
        moretext
    ↑
   tabs

These are read and joined by sendmail to form the following text value for the macro named X:

sometext\n\tmoretext\n\tmoretext

Here, the notation \n represents a newline character, and the notation \t represents a tab character.

If text is missing, the value assigned to the macro is that of an empty string; that is, a single byte that has a value of zero.

If both the name and the text are missing, the following error is printed, and that D configuration line is ignored:

configfile: line num: Name required for macro/class

Syntax of the Configuration-File Macro’s Text

The text of a macro’s value in the configuration file can contain escaped control codes. Control codes are embedded by using a backslash escape notation. The backslash escape notations understood by sendmail are listed in Table 21-2.

Table 21-2. Special characters allowed in macro text

Notation

Placed in text

\b

Backspace character

\f

Formfeed character

\n

Newline character

\r

Carriage-return character

\\

Backslash character

All other escaped characters are taken as is. For example, the notation \X becomes an X, whereas the notation \b is converted to a backspace character (usually a Ctrl-H). For example:

DXO\bc May\, 2003    becomes →  O^Hc May, 2003

Here, the \b is translated into a backspace character (Ctrl-H is shown as ^H) and the \, is translated into a literal comma character.

Note that prior to V8.8, the first comma and all characters following it were stripped from the text unless the comma was quoted or escaped. For example:

DXMay, 2003    became →  May

Beginning with V8.8 sendmail, the comma is no longer special in defined sendmail macros.

Quoted text will have the quotation marks stripped. Only double quotation marks are recognized. Multiple parts of text can be quoted, or text can be quoted entirely.

Trailing spaces are automatically stripped. If you need to keep trailing spaces you need to quote them:

DX"2003 "

Leading space characters are retained in text regardless of whether they are quoted. Spaces are harmless, provided that the macro is used only in rules (because spaces are token separators). If the macro is used to define other macros, problems can arise. For example:

Dw ourhost
DH nlm.nih.gov
Dj $w.$H

Here, the text of the $w and $H macros is used to define the $j macro. The $j macro is used in the HELO SMTP command and in the Message-ID: header line. The value given to $j in this case is:

  ourhost. nlm.nih.gov
↑         ↑
two       a space
spaces

Here, the value of $j should contain a correctly formed, fully qualified domain name. The unwanted spaces cause it to become incorrectly formed, which can cause mail to fail.

Required Macros (V8.6 and Earlier)

Table 21-3 shows the sendmail macro names that must (prior to V8.6) be given values in the configuration file.

Table 21-3. Required macros

Macro

§

Description

As of V8.7

$e

SmtpGreetingMessage on page 1093

The SMTP greeting message

The SmtpGreetingMessage option

$j

$j on page 830

Official canonical hostname

Automatically defined

$l

UnixFromLine on page 1113

Unix From format

The UnixFromLine option

$n

$n on page 836

Name used for error messages

Automatically defined

$o

OperatorChars on page 1062

Delimiter operator characters

The OperatorChars option

$q

$q on page 840

Format of the sender’s address

No longer used

Each macro is described at the end of this chapter, in Alphabetized sendmail Macros on page 798. Prior to V8.7, failure to define a required macro could have resulted in unpredictable problems. Beginning with V8.7 sendmail, no macros are required. Some are predefined[304] for you by sendmail, and others have become options.

Macro Names

Prior to V8.7 sendmail, macros could have only single characters as names. Beginning with V8.7, macros can be single-character or multicharacter.

Single-Character Names

Prior to V8.7 sendmail, the name of a macro was required to be a single character.[305] Any character can be used except the { character. However, sendmail uses many characters internally and requires that they serve specific purposes. In general, only uppercase letters should be employed as user-defined macro names. Arbitrary use of other characters can lead to unexpected results.

The character that is the macro’s name must be a single-byte character. Multibyte international characters have only the first byte (or last, depending on the machine architecture) used for the macro’s name, and what remains is joined to the text.

The high (most significant) bit of the character is always cleared (set to zero) by sendmail.

Multicharacter Names

Beginning with V8.7, macro names can be multicharacter. A multicharacter macro name must always appear inside a curly brace pair.[306] For example:

D{name}text

Here, name is one or more characters that form the macro name. If there are no characters between the curly braces, sendmail prints the following error and names the macro "{ }“:

configfile: line num: Name required for macro/class

A multicharacter macro name can contain only letters, digits, and the underscore character. Each bad character between the curly braces (including spaces) will produce the following error and cause that character to be ignored:

configfile: line num: Invalid macro/class character badchar

In general, your macro names should always begin with an uppercase character. Macro names that begin with lowercase characters are reserved for internal use by sendmail.

If the left curly brace is missing but the right is present, the macro name becomes the first letter following the D and the rest becomes the text:

Dname}text       ← sets $n to ame}text

If the right curly brace is missing but the left is present, the following error is printed, and the macro is not defined:

configfile: line num: Unbalanced { on nametext

For V8.10 and later, the maximum length of a macro name is hardcoded at 25 characters.[307] This cannot be changed with compile-time definitions. If you declare a macro name that (not counting the curly braces) is longer than 25 characters, the following error will be printed and the excess characters will become the value of an undefined name:

configfile: line num: Macro/class name ({AReallyVeryLongMacroNameHere}) too long
(25 chars max)

Because of the way multicharacter names are encoded into a single byte, there is a fixed limit on the number of multicharacter macro names that you can declare. That limit includes those multicharacter names internally defined by sendmail,[308] and those declared for class macros. There can be, at most, 96 multicharacter macro names. If you try to declare a 97th name, the following error will print and that definition will be ignored:

Macro/class {name}: too many long names

Macro Expansion: $ and $&

The value of a macro can be used by putting a $ character in front of the macro’s name. For example, consider the following definition:

DXtext

Here, the macro named X is given text as its value.

If you later prefix a macro name with a $ character, you can use that value. This is called expanding a macro:

$X

Here, the expression $X tells sendmail to use the value stored in X (the text) rather than its name (X).

For multicharacter names, the process is the same, but the name is surrounded with curly braces:

D{Xxx}textdeclare {Xxx}
${Xxx}             ← use {Xxx}

Macro Expansion Is Recursive

When text contains other macros, those other macros are also expanded. This process is recursive and continues until all macros have been expanded. For example, consider the following:

DAxxx
DByyy
DC$A.$B
DD$C.zzz

Here, the text for the macro D is $C.zzz. When the D macro is defined, it is recursively expanded like this:

$D            becomes →  $C.zzz
$C.zzz        becomes →  $A.$B.zzz
$A.$B.zzz     becomes →  xxx.$B.zzz
xxx.$B.zzz    becomes →  xxx.yyy.zzz

Notice that when sendmail recursively expands a macro, it does so one macro at a time, always expanding the leftmost macro first.

In rules, when sendmail expands a macro, it also tokenizes it. For example, placing the earlier $D in the following rule’s LHS:

R$+ @ $D      $1

causes the LHS to contain seven tokens rather than three:

R$+ @ xxx . yyy . zzz          $1

Note that the largest a recursive expansion can grow is defined at compile time with the MACBUFSIZE compile-time macro (MAX... on page 120), which defaults to 4,096 characters.

When Is a Macro Expanded?

A sendmail macro can be expanded either immediately or at runtime, depending on where the expansion takes place in the configuration file.

Macros are expanded in rule sets as the configuration file is read and parsed by sendmail, and (beginning with V8.7) so are macros in rule set names (Macros in Rule Set Names on page 686) and in database maps declared with the K configuration command (The K Configuration Command on page 882). In other configuration lines, expansion is deferred until sendmail actually needs to use that value. In yet others, macros are neither recognized nor expanded.

To illustrate, macros used in header commands are not expanded until the headers of a mail message are processed:

H?x?Full-Name: $x

Here, $x ($x on page 851) can change as sendmail is running. It contains as its value the full name of the sender. Clearly, this macro should not be expanded until that full name is known.

On the other hand, macros in rules are always expanded when the configuration file is read. Therefore, macros such as $x should never be used in rules because the configuration file is read long before mail is processed:

R$x        ($x)

Rules such as this won’t work because $x lacks a value when the configuration file is read. This rule will be expanded to become meaningless:

R      (  )

Note that the $digit positional operator (Copy by Position: $digit on page 661) in the RHS cannot be used to reference defined macros in the LHS. Consider this example, in which {HOST} has the value myhost:

R${HOST}     <$1>

The ${HOST} is expanded when the configuration file is read and is transformed into:

Rmyhost   <$1>   ← error

Here, the $1 has no wildcard operator in the LHS to reference and so will produce this error:

configfile: line num: replacement $1 out of bounds

Use Value As Is with $&

For situations in which a macro should not be recursively expanded when the configuration file is read, but rather should be used in rules as is, V8 sendmail offers the $& prefix. For example, consider the following RHS of a rule:

R...     $w.$&m

When sendmail encounters this RHS in the configuration file, it recursively expands $w into its final text value (where that text value is your hostname, such as lady). But because the m macro is prefixed with $&, it is not expanded until the rule is later evaluated at runtime.[309]

To illustrate one application of $&, consider a client/hub setup. In such a setup, all mail sent from a client machine is forwarded to the hub for eventual delivery. If the client were to run a sendmail daemon to receive mail for local delivery, a mail loop could (in the absence of an MX record) develop where a message would bounce back and fourth between the client and the hub, eventually failing.

To break such a loop, a rule must be devised that recognizes that a received message is from the hub:

R $+              $: $&r @ $&s <$1>       Get protocol and host
R smtp @ $H <$+>  $#local $: $1           Local delivery breaks a loop
R $* <$+>         $#smtp  $@ $H $: $2     Punt to hub

These rules appear in the parse rule set 0. By the time they are reached, other rules have forwarded any nonlocal mail to the hub. What is left in the workspace is a lone username. The first rule in the preceding example matches the workspace and rewrites it to be the sending protocol ($&r; see $r on page 842), an @, the sending host ($&s; see $s on page 844), and the username in angle brackets:

user     becomes →    smtp @ hub < user >

The second rule checks to make sure the message was received with the SMTP protocol from the hub. If it was, the local delivery agent is used to deliver the message on the local machine. If it was received from any other host or by any other protocol, the second rule fails and the third forwards the lone user address to the hub.

Macro Conditionals: $?, $|, and $.

Occasionally, it is necessary to test a sendmail macro to see whether a value has been assigned to it. To perform such a test, a special prefix and two operators are used. The general form is:

if        else        endif
↓         ↓        ↓
$?x text1 $| text2 $.
      ↑        ↑
if x is defined   if x is not defined

This expression yields one of two possible values: text1 if the macro named x has a value, and text2 if it doesn’t. The entire expression, starting with the $? and ending with the $., yields a single value, which can contain multiple tokens.

The following, for example, includes the configuration-file version in the SMTP greeting message but does so only if that version (in $Z; see $Z on page 853) is defined:

O SmtpGreetingMessage=$j Sendmail ($v/$?Z$Z$|generic$.) ready at $b
                                                ↑
                                                note

Here, the parenthetical version information is expressed one way if $Z has a value (such as 1.4):

($v/$Z)

but is expressed differently if $Z lacks a value:

($v/generic)

The else part ($|) of this conditional expression is optional. If it is omitted, the result is the same as if the text2 were omitted:

$?xtext1$|$.
$?xtext1$.

Both of the preceding yield the same result. If x has a value, text1 becomes the value of the entire expression. If x lacks a value, the entire expression lacks a value (produces no tokens).

Note that it is not advisable to use the $? conditional expression in rules. Such a use can have other than the intended effect because macro conditionals are expanded when the configuration file is read.

Conditionals Can Nest

V8 sendmail allows conditionals to nest. As an example, consider the following expression:

$?x $?y both $| xonly $. $| $?y yonly $| none $. $.

This is just like the example in the previous section:

$?x text1 $| text2 $.

except that text1 and text2 are both conditionals:

text1 = $?y both $| xonly $.
text2 = $?y yonly $| none $.

The grouping when conditionals nest is from the outside in. In the following example, parentheses have been inserted to show the groupings (they are not a part of either expression):

($?x  (text1)  $|  (text2)  $. )
($?x  ($?y  both $| xonly $. )  $|  ($?y  yonly $| none $. )  $. )

Interpretation is from left to right. The logic of the second line is therefore this: if both $x and $y have values, the result is both. If $x has a value but $y lacks one, the result is xonly. If $x lacks a value but $y has one, the result is yonly. And if both lack values, the result is none.

The sendmail program does not enforce or check for balance in nested conditionals. Each $? should have a corresponding $. to balance it. If they do not balance, sendmail will not detect the problem. Instead, it might interpret the expression in a way that you did not intend.

The depth to which conditionals can be nested is limited only by our ability to easily comprehend the result. More than two deep is not recommended, and more than three deep is vigorously discouraged.

Macro Xtext Translations

Some macros are assigned values from text that is supplied by outside connecting hosts. Such text cannot necessarily be trusted in rule sets, or as keys in database-map lookups.

To protect itself, sendmail modifies such text by translating whitespace characters (spaces and tabs), nonprinting characters (such as newlines and control characters), and the following list of special characters:

< > ( ) " +

Translation is the replacement of each special character with its corresponding hexadecimal value (based on U.S. ASCII), where each new hexadecimal value is prefixed with a plus character.[310] For example:

(some text)        becomes  →   +28some+20text+29

Only six macros are subject to this encoding at this time. They are listed in Table 21-4.

Table 21-4. Macros subject to xtext encoding

Macro

§

Description

${auth_authen}

${auth_authen} on page 804

RFC2554 AUTH credentials (xtext encoded with V8.13 and later)

${auth_author}

${auth_author} on page 805

RFC2554 AUTH= parameter (xtext encoded with V8.13 and later)

${cert_issuer}

${cert_issuer} on page 809

Distinguished name of certificate signer

${cert_subject}

${cert_subject} on page 809

Distinguished name of certificate (owner)

${cn_issuer}

${cn_issuer} on page 815

Common name of certificate signer

${cn_subject}

${cn_subject} on page 816

Common name of certificate

Macros with mc Configuration

The various FEATURE( )s of the mc configuration technique primarily use uppercase, single-character macro names. The complete list of them is shown in Table 21-5. Some of these are defined by using the appropriate mc configuration command (as you’ll see later). Others are predefined for you by the mc configuration technique. See the appropriate section reference for a full description of how to use each macro.

Table 21-5. Macros reserved with the mc configuration technique

Macro

§

Description

$B

$B on page 808

The BITNET relay

$C

$C on page 817

The DECnet relay

$D

$D on page 823

The local domain (unused)

$E

$E on page 824

The X.400 relay (reserved for future use)

$F

$F on page 824

The fax relay

$H

$H on page 826

The mail hub

$L

$L on page 832

The unknown local user relay

$M

$M on page 835

Whom we are masquerading as

$R

$R on page 843

The relay for unqualified names (deprecated)

$S

$S on page 845

The smart host

$U

$U on page 848

The UUCP name to override $k

$V

$V on page 850

The UUCP relay for class $=V

$W

$W on page 851

The UUCP relay for class $=W

$X

$X on page 852

The UUCP relay for class $=X

$Y

$Y on page 852

The UUCP relay for unclassified hosts

$Z

$Z on page 853

The version of this mc configuration

A few macros can be defined by using an mc configuration command. For example, here is how you define the BITNET relay with the BITNET_RELAY keyword:

define(`BITNET_RELAY', `host.domain')

See Table 21-6 for a list of the mc macros that can be defined. The leftmost column in that table shows the keyword to use.

Table 21-6. Macros declared with special mc names

mc name

Macro

§

BITNET_RELAY

$B

BITNET_RELAY mc Macro on page 603

confCF_VERSION

 

$Z on page 853

confDOMAIN_NAME

$j

$j on page 830

confLDAP_CLUSTER

${sendmailMTACluster}

${sendmailMTACluster} on page 844

confMAILER_NAME

$n

$n on page 836

DECNET_RELAY

$C

$C on page 817

FAX_RELAY

$F

FAX_RELAY mc Macro on page 604

LOCAL_RELAY

$R

$R on page 843

LUSER_RELAY

$L

LUSER_RELAY mc Macro on page 605

MAIL_HUB

$H

$H on page 826

MASQUERADE_AS( )

$M

$M on page 835

SMART_HOST

$S

$S on page 845

UUCP_RELAY

$Y

$Y on page 852

Note that MASQUERADE_AS is the single exception in Table 21-6. It is not defined with a define keyword. Rather, it is used by itself to define the setting. For example:

MASQUERADE_AS(`server')

Pitfalls

  • Macros that are given values while sendmail processes mail might not get the value expected. If that happens, careful hand-tracing of rule sets is required to find the fault.[311] For example, the value in $g ($g on page 824) is the result of sender address rewriting and rewriting by the rule set that is specified in the S= equate of the selected delivery agent. Because $g is used to define the From: header line, errors in that line should be traced through errors in the S= equate’s rule set.

  • Macros can have other macros as their values. The sendmail program expands macros recursively. As a consequence, prior to V8.10, unintentional loops in macro definitions could cause sendmail to appear to hang and to eventually segmentation-fault and core-dump. Beginning with V8.10, such recursion is caught and the following error is printed:

    configfile: line num: expand: recursion too deep (10 max)

Alphabetized sendmail Macros

The sendmail program reserves all lowercase letters, punctuation characters, and digits for its own use. For multicharacter names, it reserves all those that begin with an underscore or a lowercase letter. Table 21-7 lists all the macro names that have special internal meaning to sendmail. Included in this list are macros that are used by the mc configuration technique.[312]

Table 21-7. Reserved macros

Macro

§

Description

$_

$_ on page 801

RFC1413-validation and IP source route

$a

$a on page 802

The origin date in RFC822 format

${addr_type}

${addr_type} on page 803

Is address recipient/sender header/envelope

${alg_bits}

${alg_bits} on page 804

The number of bits in the TLS cipher

${auth_authen}

${auth_authen} on page 804

RFC2554 AUTH credentials

${auth_author}

${auth_author} on page 805

RFC2554 AUTH= parameter

${auth_ssf}

${auth_ssf} on page 806

AUTH encryption key length

${auth_type}

${auth_type} on page 806

Authentication mechanism used

$b

$b on page 807

The current date in RFC2822 format

${bodytype}

${bodytype} on page 808

The ESMTP (Extended SMTP) BODY parameter

$B

$B on page 808

The BITNET relay (mc configuration, deprecated)

$c

$c on page 808

The hop count

${cert_issuer}

${cert_issuer} on page 809

Distinguished name of certificate signer

${cert_md5}

${cert_md5} on page 809

MD5 of cert certificate

${cert_subject}

${cert_subject} on page 809

The cert subject

${cipher}

${cipher} on page 809

Cipher suite used for connection control

${cipher_bits}

${cipher_bits} on page 810

TLS encryption key length

${client_addr}

${client_addr} on page 810

The connecting host’s IP address

${client_connections}

${client_connections} on page 811

Count of simultaneous client connections (V8.13 and later)

${client_flags}

${client_flags} on page 812

The nature of the connection

${client_name}

${client_name} on page 812

The connecting host’s canonical name

${client_port}

${client_port} on page 813

The connecting host’s port number

${client_ptr}

${client_ptr} on page 813

The connecting host’s PTR record (V8.13 and later)

${client_rate}

${client_rate} on page 814

Rate of client connections (V8.13 and later)

${client_resolve}

${client_resolve} on page 814

Result of lookup of ${client_name}

${cn_issuer}

${cn_issuer} on page 815

Common name of certificate signer

${cn_subject}

${cn_subject} on page 816

Common name of certificate

${currHeader}

${currHeader} on page 816

Current header’s value

$C

$C on page 817

The DECnet relay (mc configuration)

$d

$d on page 817

The current date in Unix ctime(3) format

${daemon_addr}

${daemon_addr} on page 817

Listening daemon’s address

${daemon_family}

${daemon_family} on page 818

Listening daemon’s family

${daemon_flags}

${daemon_flags} on page 818

Listening daemon’s flags

${daemon_info}

${daemon_info} on page 819

Listening daemon’s syslog information

${daemon_name}

${daemon_name} on page 819

Listening daemon’s name

${daemon_port}

${daemon_port} on page 819

Listening daemon’s port

${deliveryMode}

${deliveryMode} on page 820

The current delivery mode

${dsn_envid}

${dsn_envid} on page 820

The DSN ENVID= value

${dsn_notify}

${dsn_notify} on page 821

The DSN NOTIFY= value

${dsn_ret}

${dsn_ret} on page 822

The DSN RET= value

$e

SmtpGreetingMessage on page 1093

The SMTP greeting message

${envid}

${envid} on page 823

The original DSN envelope ID

$E

$E on page 824

The X.400 relay (unused) (mc configuration)

$f

$f on page 824

The sender’s address

$F

$F on page 824

The fax relay (mc configuration)

$g

$g on page 824

The sender’s address relative to recipient

$h

$h on page 825

Host part of the delivery agent triple

${hdr_name}

${hdr_name} on page 825

The current header’s name

${hdrlen}

${hdrlen} on page 826

The length of ${currHeader}

$H

$H on page 826

The mail hub (mc configuration)

$i

$i on page 826

The queue identifier

${if_addr}

${if_addr} on page 827

The IP address of the receive interface

${if_addr_out}

${if_addr_out} on page 827

The IP address of the send interface

${if_family}

${if_family} on page 828

The network family of the receive interface

${if_family_out}

${if_family_out} on page 828

The network family of the send interface

${if_name}

${if_name} on page 828

The name of the receive interface

${if_name_out}

${if_name_out} on page 829

The name of the send interface

$j

$j on page 830

Official canonical name

$k

$k on page 831

UUCP node name

$l

UnixFromLine on page 1113

The Unix From format

${load_avg}

${load_avg} on page 832

The current load average

$L

$L on page 832

The unknown local user relay (mc configuration)

$m

$m on page 833

The DNS domain name

${mail_addr}

${mail_addr} on page 833

Saved $: value for MAIL From: triple

${mail_host}

${mail_host} on page 833

Saved $@ value for MAIL From: triple

${mail_mailer}

${mail_mailer} on page 834

Saved $# value for MAIL From: triple

${msg_id}

${msg_id} on page 834

Value of the Message-Id: header (V8.13 and later)

${msg_size}

${msg_size} on page 835

Size of the current message

$M

$M on page 835

Whom we are masquerading as (mc configuration)

${MTAHost}

${MTAHost} on page 835

Host for FEATURE(msp)

$n

$n on page 836

Error message sender

${nbadrcpts}

${nbadrcpts} on page 837

Count of the bad recipients in the current envelope (V8.13 and later)

${nrcpts}

${nrcpts} on page 837

Number of envelope recipients

${ntries}

${ntries} on page 838

Number of delivery attempts

$o

OperatorChars on page 1062

Token separation operators

${opMode}

${opMode} on page 839

The startup operating mode

$p

$p on page 840

The sendmail process ID

$q

$q on page 840

The default format of the sender’s address (obsolete)

${quarantine}

${quarantine} on page 841

The reason an envelope was quarantined (V8.13 and later)

${queue_interval}

${queue_interval} on page 841

The interval specified by -q

$r

$r on page 842

The protocol used

${rcpt_addr}

${rcpt_addr} on page 842

Saved $: value for RCPT To: triple

${rcpt_host}

${rcpt_host} on page 843

Saved $@ value for RCPT To: triple

${rcpt_mailer}

${rcpt_mailer} on page 843

Saved $# value for RCPT To: triple

$R

$R on page 843

The relay for unqualified names (mc configuration, deprecated)

$s

$s on page 844

The sender host’s name

${sendmailMTACluster}

${sendmailMTACluster} on page 844

The LDAP cluster to use

${server_addr}

${server_addr} on page 845

The address of the connected-to machine

${server_name}

${server_name} on page 845

The hostname of the connected-to machine

$S

$S on page 845

The smart host (mc configuration)

$t

$t on page 846

The current date and time in the form YYYYMMDDHHmm

${time}

${time} on page 846

The current time in time(3) seconds (V8.13 and later)

${tls_version}

${tls_version} on page 847

TLS/Secure Sockets Layer (SSL) version

${total_rate}

${total_rate} on page 847

Total rate of all inbound client connections (V8.13 and later)

$u

$u on page 848

Address part of a delivery agent triple

$U

$U on page 848

The UUCP name to override $k (mc configuration)

$v

$v on page 849

Version of sendmail

${verify}

${verify} on page 849

Result of cert verification

$V

$V on page 850

The UUCP relay for class $=V (mc configuration)

$w

$w on page 850

The short name of this host

$W

$W on page 851

The UUCP relay for class $=W (mc configuration)

$x

$x on page 851

The full name of the sender

$X

$X on page 852

The UUCP relay for class $=X (mc configuration)

$y

$y on page 852

Name of the controlling TTY

$Y

$Y on page 852

The UUCP relay for unclassified hosts (mc configuration)

$z

$z on page 852

The recipient’s home directory

$Z

$Z on page 853

Version of the mc configuration (mc configuration)

The following pages present a complete reference for each defined sendmail macro. They are presented in alphabetical order for ease of lookup, rather than in the order in which they typically appear in configuration files.

$_

RFC1413 validation and IP source route V8.1 and later

RFC1413, Identification Protocol, describes a method for identifying the user and host that initiate network connections.[313] It relies on the originating host, which must be running the identd(8) daemon.

When the V8 sendmail daemon receives a network connection request (and if the Timeout.ident option, Timeout.ident (V8.6 and later) on page 1104, is nonzero) it attempts to connect to the originating host’s identd service. If the originating host properly supports identification, sendmail reads the login name of the user who initiated the connection (although sendmail will read whatever the other side sends, including garbage). The sendmail program then appends an @ and the originating hostname to what it interprets as the username. If the originating hostname is an IP address in square brackets, sendmail attempts to convert the number to a hostname. The final result, in the form user@host, is assigned to $_.

When sendmail is run on the local machine, it sets $_ to be the name of the user that corresponds to the user-id of the process that ran sendmail. It gets that name by calling getpwuid(3). If the call fails, the name is set to the string:

Unknown UID: num

Here, num is the user-id for which a login name could not be found.

Next, an @ and the name of the local machine are appended to the name, and the result is assigned to $_.

Beginning with V8.7 sendmail, attempts at IP source routing can also be stored in this macro. If sendmail was compiled with IP_SRCROUTE defined, that IP source routing information will be added to $_ after the user and host described earlier. The format of this additional information is described in IP_SRCROUTE on page 116.

The $_ macro is used in the standard Received: header like this:

HReceived: $?sfrom $s $.$?_($?s$|from $.$_)$.

Note that the $& prefix is necessary when you reference this macro in rules (that is, use $&_, not $_).

$a

The origin date in RFC2822 format All versions

The $a macro holds the origin date of a mail message (the date and time that the original message was sent). It holds a date in ARPAnet format, defined in RFC2822, Pitfalls.

The sendmail program obtains that date in one of the following four ways:

  • When sendmail first begins to run, it presets several date-oriented macros internally to the current date and time. Among those are the macros $t, $d, $b, and $a.

  • Whenever sendmail collects information from the stored header of a message (whether after message collection, during processing of the queue, or when saving to the queue), it sets the value of $a. If a Posted-Date: header exists, the date from that line is used. Otherwise, if a Date: header exists, that date is used. Note that no check is made by sendmail to ensure that the date in $a is, indeed, in RFC2822 format. Of necessity, it must trust that the originating program has adhered to that standard.

  • When sendmail notifies the user of an error, it takes the origin date from $b (the current date in RFC2822 format) and places that value into $a.

$a is chiefly intended for use in configuration-file header definitions. It can also be used in delivery agent A= equates (argument vectors), although it is of little value in that case.

$a is transient. If defined in the configuration file or in the command line, that definition might be ignored by sendmail. Note that the $& prefix is necessary when you reference this macro in rules (that is, use $&a, not $a).

${addr_type}

Is address recipient/sender header/envelope V8.10 and later

Some rule sets are passed only a recipient or a sender address, supplied from either a header or the envelope. Examples are rule sets 1 and 2, and the rule sets indicated by the R= and S= equates. Other rule sets, such as the canonify rule set 3, can be called with any combination.

When designing rules, it might be necessary to know whether those rules are dealing with a sender or a recipient, and whether the address is from the envelope or a header. Beginning with V8.10, sendmail offers the ${addr_type} macro as a means to solve that very problem. As shown in Table 21-8, the ${addr_type} macro can hold any of several pairs of characters, depending on whether the address is from the envelope or a header, and whether the address is that of a sender or a recipient.

Table 21-8. Possible values for the {addr_type} macro

Value

Meaning

e s

An envelope sender address

e r

An envelope recipient address

h

A header recipient address or header sender address

To illustrate one use for this ${addr_type} macro’s value, consider a rule set that screens addresses and rejects any that are found in a database of spam sender hosts:

LOCAL_CONFIG
Kspammers hash /etc/mail/spammers

LOCAL_RULESETS
SDomainLookup
R $+ <@ $=w .>          $@ OK        local users are always OK
R $+ <@ $+>             $: $1 <@ $2 > <$&{addr_type}>
R $+ <@ $+> <e r>       $@ OK        we only screen envelope senders.
R $+ <@ $+> <h>         $@ OK        we don't screen header addresses.
R $+ <@ $+> <$*>        $(spammers $2 $: OK $)
R OK                    $@ OK
R $*                    $@ ERROR

Under the LOCAL_CONFIG section of this mc configuration file, we define a database, /etc/mail/spammers, that contains a list of sites we want to reject for spamming.

Under the LOCAL_RULESETS section, we declare the DomainLookup rule set. We might call this rule set from other policy rule sets, such as Local_check_mail (Local_check_mail and check_mail on page 255).

The first rule accepts anything that looks like a local address. The second rule appends the value of the ${addr_type} macro to the workspace. The third and fourth rules accept all envelope recipient addresses and all header addresses, but not envelope sender addresses.

The fifth rule looks up the envelope sender’s host in the spammers database. If that hostname is found, its value is returned (a spam site was found). If it is not found in the database, OK is returned (the site is not a spam site). The last two rules simply return OK or ERROR to indicate the nature of the hostname. Depending on how you employ this rule set, you might wish to return more complex information, such as the original workspace augmented with good or bad.

Prior to V8.14, if the address was a header address, neither the s nor the r would be present. Beginning with V8.14, when this ${addr_type} shows a header, the difference between a sender and recipient header will be shown by the presence of an s or an r.

${addr_type} is transient. If it is defined in the configuration file or command line, that definition can be ignored by sendmail. Note that it is currently not possible to differentiate between a header sender and a header recipient with this macro.

Also note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{addr_type}, not ${addr_type}).

${alg_bits}

The number of bits in the TLS cipher V8.11 and later

TLS is a protocol implemented with the OpenSSL library. When the remote site recognizes that the local sendmail supports the STARTTLS ESMTP extension, and if policy at the remote site allows it to, the remote site sends the STARTTLS command. If that command is accepted by the local sendmail, the two sides negotiate a secure connection. Part of the information determined in this negotiation is the cipher to use. Once a cipher has been accepted, and the connection allowed, sendmail updates the value of several macros, among which is this ${alg_bits} macro.

The ${alg_bits} macro holds as its value the number of bits of the symmetric encryption in the cipher that was agreed upon. That value is a text representation of a positive integer, or, if there was no cipher, the number zero.

When sendmail logs the start of a TLS session, it does so with a line such as this:

STARTTLS=who, relay=host, version=vers, verify=verify, cipher=cipher, bits=
algbits/cbits

Here, the value assigned to this ${alg_bits} macro is printed following the bits= and before the slash.

The ${alg_bits} macro is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{alg_bits}, not ${alg_bits}).

${auth_authen}

RFC2554 AUTH credentials V8.10 and later

A server offers authentication by presenting the AUTH keyword to the connecting site, following that with the types of mechanisms supported:

250-host.domain Hello some.domain, pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH DIGEST-MD5 CRAM-MD5                  ← note this line
250-DELIVERBY
250 HELP

If the connecting site wishes to authenticate itself, it replies with an AUTH command indicating the type of mechanism preferred:

AUTH X5                                                           ← client sends
504 Unrecognized authentication type.                             ← server replies
AUTH CRAM-MD5                                                     ← client sends
334  PENCeUxFREJoU0NnbmhNWitOMjNGNndAZWx3b29kLmlubm9zb2Z0LmNvbT4= ← server replies
ZnJlZCA5ZTk1YWVlMDljNDBhZjJiODRhMGMyYjNiYmFlNzg2ZQ=  =                 ← client
sends
235 Authentication successful.                                    ← server replies

Here, the client first asks for X5 authentication, which the server rejects. The client next asks for CRAM-MD5. The server says it can support that by replying with a 334 followed by a challenge string. The client replies to the challenge with an appropriate reply string, and the authentication is successful (as shown in the last line).

If authentication is successful, this ${auth_authen} macro is assigned the authentication credentials that were approved as its value. The form of the credentials depends on the encryption used. It could be a simple username (such as bob) or a username at a realm (such as bob@some.domain).

The client can then offer a different user, rather than the envelope sender, to authenticate on behalf of the envelope sender. This is done by adding an AUTH= parameter to the MAIL From: keyword:

MAIL From: <user@host.domain> AUTH=address

The address is assigned to the {auth_author} macro, and the trust_auth rule set (SASL and Rule Sets on page 194) is called to make further policy decisions, with the AUTH= parameter in its workspace.

The ${auth_authen} macro is useful for adding your own rules to the Local_trust_auth rule set.

${auth_authen} is transient. If defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{auth_authen}, not ${auth_authen}).

Note that, beginning with V8.13, the value to be stored into this macro is first xtext encoded, then stored (Macro Xtext Translations on page 795).

${auth_author}

RFC2554 AUTH= parameter V8.10 and later

As part of the RFC2554 authentication scheme, a client can ask whether a user other than the envelope sender is allowed to authenticate on behalf of the envelope sender. This is done by adding an AUTH= parameter to the MAIL From: keyword:

MAIL From: <user@host.domain> AUTH=address

This ${auth_author} macro is assigned the address that followed the MAIL From: AUTH= extension.

The ${auth_author} macro is useful for adding your own rules to the Local_trust_auth rule set. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{auth_author}, not ${auth_author}).

Note that beginning with V8.13, the value to be stored into this macro is first xtext-encoded, then stored (Macro Xtext Translations on page 795).

${auth_author} is transient. If defined in the configuration file or in the command line, that definition can be ignored by sendmail.

${auth_ssf}

AUTH encryption key length V8.11 and later

If a connection is authenticated with RFC2554 AUTH, and if an encryption layer is used, a key length will be associated with the encryption used. This ${auth_ssf} macro is assigned that length, which is an integer representation of the number of bits used. This is the actual key length.

This ${auth_ssf} macro is used in two places in the default sendmail.cf file. It is used by a common subroutine called from the tls_rcpt (The tls_rcpt rule set on page 215), tls_client (The access database with tls_server and tls_client on page 214), and tls_server (The access database with tls_server and tls_client on page 214) rule sets. It is also used as part of the default Received: header:

HReceived: $?sfrom $s $.$?_($?s$|from $.$_)
        $.$?{auth_type}(authenticated$?{auth_ssf} bits=${auth_ssf}$.)
        $.by $j ($v/$Z)$?r with $r$. id $i$?{tls_version}
        (version=${tls_version} cipher=${cipher} bits=${cipher_bits}
verify=${verify})$.$?u
        for $u; $|;
        $.$b

The ${auth_ssf} macro is useful for adding your own rules to policy rule sets. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{auth_ssf}, not ${auth_ssf}).

${auth_ssf} is transient. If defined in the configuration file or in the command line, that definition can be ignored by sendmail.

${auth_type}

Authentication mechanism used V8.10 and later

A server offers authentication by presenting the AUTH keyword to the connecting site, following that with the types of authentication mechanisms supported:

250-host.domain Hello some.domain, pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH DIGEST-MD5 CRAM-MD5                  ← note this line
250-DELIVERBY
250 HELP

If the connecting site wishes to authenticate itself, it replies with an AUTH command indicating the mechanism preferred:

AUTH CRAM-MD5                                                     ← client sends

Once it is selected, that mechanism is placed into this ${auth_type} macro. If no mechanism is selected (none is offered, or none is accepted) or if the act of authentication fails, ${auth_type} becomes undefined (NULL).

If the authentication is accepted, the Received: header is updated to reflect that:

HReceived: $?sfrom $s $.$?_($?s$|from $.$_)
        $.$?{auth_type}(authenticated$?{auth_ssf} bits=${auth_ssf}$.)
        $.by $j ($v/$Z)$?r with $r$. id $i$?{tls_version}
        (version=${tls_version} cipher=${cipher} bits=${cipher_bits}
verify=${verify})$.$?u
        for $u; $|;
        $.$b

Here, if the connection were authenticated, the second line of the Received: header would look like this:

(authenticated bits=bits)
(authenticated)                       ← if no encryption negotiated

The ${auth_type} macro is useful for adding your own rules to policy rule sets, such as to the Local_trust_auth rule set. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{auth_type}, not ${auth_type}).

${auth_type} is transient. If defined in the configuration file or in the command line, that definition can be ignored by sendmail.

$b

The current date in RFC2822 format All versions

The $b macro contains the current date in ARPAnet format, as defined in RFC822, Support SMTP AUTH, and amended by RFC2822, Pitfalls.

Because $b holds the current date and time, sendmail frequently updates the value in that macro. When sendmail first starts to run, it places the current date and time into $b. Thereafter, each time an SMTP connection is made and each time the queue is processed, the value of the date and time in that macro is updated.

If the system call to time(3) should fail, the value stored in $b becomes Wed Dec 31 15:59:59 1969,[314] and no other indication of an error is given.

$b is chiefly intended for use in configuration-file header definitions that require ARPAnet format (such as Received:, Received: on page 1162).

$b is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&b, not $b).

${bodytype}

The ESMTP BODY parameter V8.8 and later

MIME support in V8 sendmail has been coupled to ESMTP of the new BODY parameter for the MAIL From: command. That parameter tells sendmail whether it is dealing with 7-bit or 8-bit MIME data:[315]

MAIL From:<address> BODY=7BIT
MAIL From:<address> BODY=8BITMIME

The parameter specified for the BODY (BIT or BITMIME) is the value stored in the ${bodytype} macro.

The ${bodytype} macro is intended to be used as part of the delivery agent’s A= equate (A= on page 738). It provides a means to pass this information to delivery agent programs as part of their command lines.

${bodytype} is transient. If defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that the -B command-line switch (-B on page 232) can be used to specify a value to be stored in ${bodytype}, but only for initial mail submission. Also note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{bodytype}, not ${bodytype}).

$B

The BITNET relay mc configuration, deprecated

The $B macro contains the name of the host for relaying mail to a BITNET server. That server is defined using the BITNET_RELAY mc macro (BITNET_RELAY mc Macro on page 603). You should not use this $B macro directly because it might change in a future release of sendmail.

$c

The hop count All versions

The $c macro is used to store the number of times a mail message has been forwarded from site to site. It is a count of the number of Received:, Via:, and Mail-From: header lines in a message.

The value in $c is not used by sendmail. Rather, it is made available for use in configuration-file header-line definitions. When calculating the hop count for comparison to the MaxHopCount option (MaxHopCount on page 1046) sendmail uses internal variables.

$c is transient. If defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&c, not $c).

${cert_issuer}

Distinguished name of certificate issuer V8.11 and later

As a part of the STARTTLS form of authentication and encryption, certificates are usually exchanged. The certificate presented by the other side is signed by a certificate authority, and this ${cert_issuer} macro is assigned the distinguished name (the DN) of that certificate authority. That value might look like this:

/C=US/ST=California/L=Berkeley/O=Sendmail.org/CN=Sendmail+20CA/

See The access database and Local_Relay_Auth on page 213 for an illustration of one use for ${cert_issuer}. See Macro Xtext Translations on page 795 to find how and why the value in this macro undergoes special translation.

${cert_issuer} is transient. If defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{cert_issuer}, not ${cert_issuer}).

${cert_md5}

MD5 of cert certificate V8.11 and later

As a part of the STARTTLS form of authentication and encryption, certificates are usually exchanged. This ${cert_md5} macro is assigned the result of an md5(1) 128-bit “fingerprint” of the certificate presented by the other side. That value might look like this:

5e5bb09c1a3488a3216aaabe23081caf

The ${cert_md5} macro is not used in the default configuration file, but is available for use in rule sets of your own design. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{cert_md5}, not ${cert_md5}).

${cert_md5} is transient. If defined in the configuration file or in the command line, that definition can be ignored by sendmail.

${cert_subject}

The cert subject V8.11 and later

As a part of the STARTTLS form of authentication and encryption, certificates are usually exchanged. This ${cert_subject} macro is assigned the distinguished name (the DN) of the certificate presented by the other side. That value might look like this:

/C=US/ST=California/L=Berkeley/O=Sendmail.org/CN=smtp.sendmail.org/

See The access database and Local_Relay_Auth on page 213 for an illustration of one use for ${cert_subject}. See Macro Xtext Translations on page 795 to find how and why the value in this macro undergoes special translation.

${cert_subject} is transient. If defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{cert_subject}, not ${cert_subject}).

${cipher}

Cipher suite used for connection V8.11 and later

When an inbound connection is made, the connecting client can request to use STARTTLS for an encrypted session. When an outbound connection is made, the local machine may request to use STARTTLS for an encrypted session with the remote host. In either scenario, after agreement has been made to encrypt, the ${alg_bits}, ${cert_issuer}, ${cert_subject}, ${cert}, ${cipher_bits}, ${cipher}, ${cn_issuer}, ${cn_subject}, ${tls_version}, and ${verify} macros are given values that describe the nature of the connection.

This ${cipher} macro contains as its value the cipher suite used for the connection. The possible suites are text values that include EDH-DSS-DES-CBC3-SHA, EDH-RSA-DES-CBC3-SHA, DES-CBC-MD5, and DES-CBC3-SHA, among others. If ${tls_version} has a value, the value in ${cipher} is included as part of the text in the Received: header:

(version=${tls_version} cipher=${cipher} bits=${cipher_bits} verify=${verify})

If ${tls_version} lacks a value, the preceding text is not included.

${cipher} is transient. If it is defined in the configuration file or in the command line, that definition is ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{cipher}, not ${cipher}).

${cipher_bits}

TLS encryption key length V8.11 and later

When an inbound connection is made, the connecting client can request to use STARTTLS for an encrypted session. When an outbound connection is made, the local machine can request to use STARTTLS for an encrypted session with the remote host. In either scenario, after agreement has been made to encrypt, the ${alg_bits}, ${cert_issuer}, ${cert_subject}, ${cert}, ${cipher_bits}, ${cipher}, ${cn_issuer}, ${cn_subject}, ${tls_version}, and ${verify} macros are given values that describe the nature of the connection.

This ${cipher_bits} macro contains as its value the key length (in bits) of the symmetric encryption algorithm used for a TLS connection. The value is a text representation of an integer value. If ${tls_version} has a value, the value in ${cipher_bits} is included as part of the text in the Received: header:

(version=${tls_version} cipher=${cipher} bits=${cipher_bits} verify=${verify})

If ${tls_version} lacks a value, the preceding text is not included.

${cipher_bits} is transient. If it is defined in the configuration file or in the command line, that definition is ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{cipher_bits}, not ${cipher_bits}).

${client_addr}

The connecting host’s IP address V8.8 and later

The ${client_addr} macro is assigned its value when a host connects to the running daemon. The value assigned is the IP address of that connecting host and is the same as the IP address stored in the $_ macro, but without the surrounding square brackets and other non-IP information.

The ${client_addr} macro can be useful in the Local_check_rcpt (Local_check_rcpt and check_rcpt on page 257) and Local_check_mail (Local_check_mail and check_mail on page 255) rule sets. It can, for example, be used to detect whether an external host is trying to send external mail through your outgoing firewall machine:

LOCAL_CONFIG
D{ourdomain}123.45.6

LOCAL_RULESETS
SLocal_check_mail
R $*                    $: $&{client_addr}
R ${ourdomain} . $-     $@ OK our domain
R $*                    $#error $@ 5.7.1 $: "550 cannot send out from the outside"

Here, the first rule transfers the value of ${client_addr} into the workspace. The $& prefix (Use Value As Is with $& on page 793) prevents that macro from wrongly being expanded when the configuration file is read. The second rule compares the domain part of your IP domain (that of your internal network) to the workspace. If they match, the connection is from a host in your internal domain space. If not, an error is generated in response to the MAIL From: command.

Note that this rule set rejects all mail coming from outside your network, which might be overkill (depending, of course, on what you want). It is really useful only at sites that have two firewalls, one for incoming traffic and one for outgoing traffic. This rule set might go on the outgoing firewall.

${client_addr} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that ${client_addr} is not guaranteed to be available in the check_compat rule set (The check_compat Rule Set on page 259). Note also that a $& prefix is necessary when you reference this macro in rules (that is, use $&{client_addr}, not ${client_addr}).

${client_connections}

Count of simultaneous client connections V8.13 and later

When a host connects to the listening sendmail server, that server forks a child copy of itself to handle the new connection. Before forking, the server increments the connection count associated with the IP address of the connecting client. When the forked child finishes and exits, the server decrements that count.

Beginning with V8.13 sendmail, the ${client_connections} macro holds that count as its value, making it available for use in rule sets.

With V8.13, if you declare FEATURE(conncontrol) (FEATURE(conncontrol) on page 619), a rule set called ConnControl will be added to your configuration file that looks up the current IP address in the access database. The source text file for the access database may contain that address with a literal ClientConn: prefix, as, for example:

ClientConn:123.45.67.89          12

Note that the literal prefix is followed by the IP address to be looked up, then tabs or spaces,[316] and lastly by the limit to impose on the maximum number of connections for that IP address.

If the number of connections (as stored in this ${client_connections} macro) exceeds the limit imposed inside the access database, the new connection is rejected with the following error:

433 4.3.0 Too many open connections.

${client_flags}

The nature of the connection V8.10 and later

The ${client_flags} macro holds the flags specified by the ClientPortOptions option’s Modify parameter (DaemonPortOptions=Modify= on page 996). This ${client_flags} macro is given a value only after a connection is made, because the Modify flags can vary by the family of the connection. If no Modify flags were specified, ${client_flags} is given an empty string as its value.

The value letters from the ClientPortOptions=Modify option are stored into this macro after the connection is made. Each letter is separated from the others by a space, and capital letters are doubled. That is, for example, if that option was declared like this:

ClientPortOptions=Modify=bcE

the value of the ${client_flags} macro would become:

b c EE

Capital letters are doubled so that they can be detected in rules. Recall that rules view their workspace in a case-insensitive manner (that is, e is the same as E). Doubling allows the LHS of rules to be designed like this:

R $* e $*      ← match a lowercase e
R $* ee $*     ← match an uppercase E

${client_flags} is not used in the default configuration file, but is available for you to use in rules of your own design. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{client_flags}, not ${client_flags}).

${client_flags} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail.

${client_name}

The connecting host’s canonical name V8.8 and later

The ${client_name} macro is assigned its value when a host connects to the running daemon. This macro holds as its value the canonical hostname of that connecting host, which is the same as the hostname stored in the $_ macro.

The ${client_name} macro is useful in the Local_check_rcpt (Local_check_rcpt and check_rcpt on page 257), Local_check_mail (Local_check_mail and check_mail on page 255), and Local_check_relay (Local_check_relay and check_relay on page 252) rule sets. It can, for example, be used to see whether the connecting host is your firewall machine:

LOCAL_CONFIG
D{FireWallHost}fw.our.domain

LOCAL_RULESETS
SLocal_check_mail
R $*                     $: $&{client_name}
R ${FireWallHost}        $@ Okay our firewall machine
R $*                     $#error $@ 5.7.1 $: "550 can accept only from our firewall"

Here, the first rule transfers the value of ${client_name} into the workspace. The $& prefix (Use Value As Is with $& on page 793) prevents that macro from wrongly being expanded when the configuration file is read. The second rule compares the name of the firewall to that workspace. If they match, the connecting host was, indeed, the firewall machine.

${client_name} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that ${client_name} is not guaranteed to be available in the check_compat rule set (The check_compat Rule Set on page 259). Also note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{client_name}, not ${client_name}).

${client_port}

The connecting host’s port number V8.10 and later

Rule sets cannot know which port a connecting host used to connect to the listening daemon unless that port number is stored in a macro. This ${client_port} macro holds as its value that port number. This port number should not be confused with the port number on which the listening daemon accepted the connection (usually 25). This is the port number used by the other MTA to establish its outbound connection to your listening daemon.

One use for this macro might be to log the client port so that you can develop a profile of ports used by spam sites (and perhaps find a pattern):

LOCAL_CONFIG
Klog syslog

LOCAL_RULESETS
SLocal_check_mail
R $*       $@ $(log Port_Stat &${client_name} $&{client_addr} $&{client_port} $)

Here, we first define a database map of type syslog and name it log. Then we declare the Local_check_mail rule set (Local_check_mail and check_mail on page 255), which is called just after the MAIL From: command is received. The single rule in that rule set uses the log database map to syslog the client’s name, address, and port number. The $@ beginning the RHS causes the rule set to return immediately after logging.

${client_port} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{client_port}, not ${client_port}).

${client_ptr}

Connecting client’s PTR record V8.13 and later

When a client host connects to the listening sendmail server, that server knows the IP address of the connecting client but not its hostname. To find the hostname, sendmail performs a reverse lookup to find a PTR record which contains the host’s name. Beginning with V8.13, the result of that lookup (the host’s name) is stored in the ${client_ptr} macro.

Note that if (and only if) the ${client_resolve} macro (${client_resolve} on page 814) contains a literal OK, will this ${client_ptr} macro hold the same value that the ${client_name} macro (${client_name} on page 812) holds.

${client_ptr} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{client_ptr}, not ${client_ptr}).

${client_rate}

Rate of client connections V8.13 and later

When a host connects to the listening sendmail server, the server forks a child to handle the new connection. Before forking, the server increments the count of total inbound connections from that particular client identified by its IP address. The rate of those connections is then updated inside a specific window of time (defined by the ConnectionRateWindowSize option; ConnectionRateWindowSize on page 989), which defaults to 60 seconds.

Beginning with V8.13 sendmail, the ${client_rate} macro holds that count as its value, making it available to use in rule sets.

Also beginning with V8.13, if you declare FEATURE(ratecontrol) (FEATURE(ratecontrol) on page 638), a rule set called RateControl will be added to your configuration file that looks up the current IP address in the access database. The source text file for the access database may contain that address with a literal ClientRate: prefix, as, for example:

ClientRate:123.45.67.89          4

Note that the literal prefix is followed by the IP address to be looked up, then tabs or spaces,[317] and lastly by the limit to impose for the maximum connection rate for that IP address.

If the current rate (as stored in this ${client_rate} macro) exceeds the limit imposed inside the access database, the new connection is rejected with the following error:

433 4.3.0 Connection rate limit exceeded.

If you are interested in knowing the total rate of connections for all clients, see the ${total_rate} macro (${total_rate} on page 847).

${client_resolve}

Result of lookup of ${client_name} V8.10 and later

When sendmail first assigns a value to the ${client_name} macro (${client_name} on page 812) it also looks up the hostname of that connecting client with DNS. Table 21-9 shows the possible results of that lookup.

Table 21-9. Possible values for the ${client_resolve} macro

Value

Meaning

OK

The address lookup was successful.

FAIL

The lookup resulted in a permanent failure.

FORGED

The forward lookup doesn’t match the reverse lookup.

TEMP

The lookup resulted in a temporary failure.

The ${client_resolve} macro is useful in the Local_check_rcpt (Local_check_rcpt and check_rcpt on page 257), Local_check_mail (Local_check_mail and check_mail on page 255), and Local_check_relay (Local_check_relay and check_relay on page 252) rule sets. It can, for example, be used to accept mail only from machines whose hostname can be successfully looked up with DNS:

LOCAL_RULESETS
SLocal_check_mail
R$*                    $: $&{client_resolve}
ROK                    $@ Okay
RTEMP                  $#error $@ 4.7.1 $: "450 Can't resolve hostname just now."
R$*                    $#error $@ 5.7.1 $: "550 Sending hostname must resolve!"

Here, the first rule transfers the value of ${client_resolve} into the workspace. The $& prefix (Use Value As Is with $& on page 793) prevents that macro from wrongly being expanded when the configuration file is read. The second rule accepts the address if it can be looked up. The third rule defers acceptance of any sender address that results in a temporary lookup error. The last rule bounces mail from any host that cannot be looked up, or that appears to be a forged address.

${client_resolve} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that ${client_resolve} is not guaranteed to be available in the check_compat rule set (The check_compat Rule Set on page 259). Also note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{client_resolve}, not ${client_resolve}).

${cn_issuer}

Common name of certificate signer V8.11 and later

As a part of the STARTTLS form of authentication and encryption, certificates are usually exchanged. The certificate presented by the other side must be authorized by a certificate authority (CA). When it is, this ${cn_issuer} macro is assigned the common name (CN) of the CA that signed that certificate. That value might look like this:

Tan+20Woo         ← a person's name
Woo+20Poultry     ← a business name

See Macro Xtext Translations on page 795 to find how and why the value in this macro undergoes special translation.

${cn_issuer} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Also note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{cn_issuer}, not ${cn_issuer}).

${cn_subject}

Common name of certificate V8.11 and later

As a part of the STARTTLS form of authentication and encryption, certificates are usually exchanged. If a certificate is presented by the other side, this ${cn_issuer} macro is assigned the CN of that certificate. That value might look like this:

Juan+20Garcia           ← a person's name
Garcia's+20Software     ← a business name

See Macro Xtext Translations on page 795 to find how and why the value in this macro undergoes special translation.

${cn_subject} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Also note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{cn_subject}, not ${cn_subject}).

${currHeader}

Current header’s value V8.10 and later

The ${currHeader} macro is given a value whenever a header-checking rule set is called. Header rule set checking is declared as part of the H configuration command, as for example:

LOCAL_RULESETS
HSubject: $>ScreenSubject

Here, sendmail will gather the text following the Subject: header in the mail message and supply that text to the ScreenSubject rule set. Usually, that text is treated as an address. All RFC comments are stripped and extra interior spaces are removed, but when you want that text to be supplied intact and as is to a rule set, you can employ this ${currHeader} macro.

To illustrate, consider the need to reject messages that have 10 or more consecutive spaces in the Subject: header. Such Subject: headers often indicate a spam message:

Subject: Rates DROPPED! Lenders COMPETE for mortgage LOANS!                     83419

One way to screen for such headers might look like this:

LOCAL_CONFIG
Ksubjspaces regex -a.FOUND [ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]

LOCAL_RULESETS
HSubject: $>+ScreenSubject

SScreenSubject
R $*            $: $1 $(subjspaces $1 $)                           ← won't work
R $* . FOUND    $#error $@ 5.7.0 $: "553 Subject: header indicates a spam."
R $*            $: OK

The K line sets up a regular expression that will look for 10 consecutive space characters. The first rule in the rule set attempts to find 10 consecutive spaces in the workspace by passing the workspace to the subjspaces regular expression map.

But this won’t work. The workspace contains the Subject: header’s text after that text has been stripped of RFC comments, and after multiple consecutive spaces have been reduced to one space. Clearly, the reduction of spaces will prevent 10 consecutive spaces from being found. To make this screening work, the first rule needs to be rewritten like this:

R $*            $: $1 $(subjspaces $&{currHeader} $)              ← use this instead

Here, the subjspaces regular expression database map is instead given the value of the ${currHeader} macro. That value is the Subject: header’s text without anything removed. All the original spaces are intact, and the spam message will be successfully rejected.

For another example of a use for this ${currHeader} macro, see Use $>+ to Include RFC2822 Comments on page 1131.

$C

The DECnet relay mc configuration

$C holds the hostname set by the DECNET_RELAY mc macro (DECNET_RELAY mc Macro on page 604). Do not use this macro directly, as it might change in future versions of sendmail.

$d

The current date in Unix ctime(3) format All versions

The $d macro holds the current date and time. $d is given its value at the same time $b is defined. The only difference between the two is that $b contains the date in RFC822 format, whereas $d contains the same date in Unix ctime(3) format.

The form of a date in ctime(3) format is generally:[318]

Fri Jan 13 01:03:52 2006\n

When sendmail stores this form of date into $d, it converts the trailing newline (the \n) into a zero, thus stripping the newline from the date.

${daemon_addr}

Listening daemon’s address V8.10 and later

The sendmail program can listen for (await) inbound connections on more than one interface, where each interface can have one or more addresses associated with it. The ${daemon_addr} macro contains the address upon which the daemon was listening when it accepted the inbound connection. This macro is given the value declared by the DaemonPortOptions=Addr option (DaemonPortOptions=Addr= on page 994) associated with that connection each time rule sets are called.

The format of the value stored in ${daemon_addr} is based upon the setting of the DaemonPortOptions=Family option (DaemonPortOptions=Family= on page 995). If that setting is inet (the default) or inet6, the address in ${daemon_addr} will correspondingly look like one of the following:

123.45.67.89                 ← an IPv4 address
IPv6:2002:c0a8:51d2::23f4    ← an IPv6 address

If the DaemonPortOptions=Addr option is undeclared, the default (with the inet family’s format) becomes 0.0.0.0 for IPv4, or (with the inet6 family’s format) IPv6::: for IPv6.

This ${daemon_addr} macro is not used in the rule sets supplied with sendmail. It is, however, available for your use when designing custom rule sets. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{daemon_addr}, not ${daemon_addr}).

${daemon_addr} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail.

${daemon_family}

Listening daemon’s family V8.10 and later

The sendmail program can listen for (await) inbound connections on more than one interface, where each interface can employ any one of five possible protocol families. Possible families are inet for AF_INET, inet6 for AF_INET6, iso for AF_ISO, ns for AF_NS, and x.25 for AF_CCITT. The value stored in this ${daemon_family} macro is taken from the DaemonPortOptions=Family option (DaemonPortOptions=Family= on page 995) whenever a message is processed by rule sets, and reflects the family of the interface upon which the inbound connection was received.

This ${daemon_family} macro is not used in the rule sets supplied with sendmail. It is, however, available for your use when designing custom rule sets. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{daemon_family}, not ${daemon_family}).

${daemon_family} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail.

${daemon_flags}

Listening daemon’s flags V8.10 and later

The letters that form the value of the DaemonPortOptions=Modify option (DaemonPortOptions=Modify= on page 996) are stored in the ${daemon_flags} macro when the daemon first starts up. If the Modify was not specified for that port, the value stored in ${daemon_flags} is an empty string.

When a value is stored in ${daemon_flags}, each letter in that value is separated from the others by a space, and capital letters are doubled. If that option, for example, is declared like this:

DaemonPortOptions=Modify=bcE

the value of the ${daemon_flags} macro will become:

b c EE

Capital letters are doubled so that they can be detected in rules. Recall that rules view their workspace in a case-insensitive manner (that is, e is the same as E). Doubling allows the LHS of rules to be designed like this:

R $* e $*      ← match a lowercase E
R $* ee $*     ← match an uppercase E

${daemon_flags} is not used in the default configuration file, but it is available for you to use in rules of your own design. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{daemon_flags}, not ${daemon_flags}).

${daemon_flags} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail.

${daemon_info}

Listening daemon’s syslog information V8.10 and later

Whenever sendmail starts running as a daemon, it places the same information that it logs into this ${daemon_info} macro. For example, the following syslog information:

starting daemon (8.10.1): SMTP+queueing@01:00:00

would cause the value of ${daemon_info} to become:

SMTP+queueing@01:00:00

As distributed, this ${daemon_info} macro is not used in the configuration file. It is, however, available to you for use in designing your own particular rule sets. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{daemon_info}, not ${daemon_info}).

${daemon_info} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail.

${daemon_name}

Listening daemon’s name V8.10 and later

The ${daemon_name} macro contains the value of the DaemonPortOptions=Name option (DaemonPortOptions=Name= on page 996) whenever an inbound connection is accepted. The names assigned in the default configuration file are MTA (for the daemon that listens on port 25) and MSA (for the MSP daemon that listens on port 587).

As distributed, this ${daemon_name} macro is not used in the configuration file. It is, however, available to you for use in designing your own particular rule sets. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{daemon_name}, not ${daemon_name}).

${daemon_name} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail.

${daemon_port}

Listening daemon’s port V8.10 and later

The ${daemon_port} macro contains the value of the DaemonPortOptions=Port option (DaemonPortOptions=Port= on page 997) whenever mail is processed by the daemon listening on that port.

As distributed, this ${daemon_port} macro is not used in the configuration file. It is, however, available to you for use in designing your own particular rule sets. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{daemon_port}, not ${daemon_port}).

${daemon_port} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail.

${deliveryMode}

The current delivery mode V8.9 and later

The sendmail program can run in any of several modes, each of which determines its behavior. When sendmail first starts to run, it sets its mode based on the setting of its DeliveryMode option (DeliveryMode on page 1004) and places the character representing that mode into this ${deliveryMode} macro. If sendmail is run with the -odi command-line switch, for example, this ${deliveryMode} macro is given the value i. Once the sendmail program is running, its delivery mode can be changed for a variety of reasons. When it starts to process the queue, for example, the mode is changed to d (for deliver).

One use for the ${deliveryMode} macro can be seen in the standard configuration file:

SBasic_check_relay
# check for deferred delivery mode
R$*                     $: < $&{deliveryMode} > $1
R< d > $*               $@ deferred

Here, the Basic_check_relay rule set is called to determine whether mail from the connecting host should be accepted. Because the hostname of the connecting host is not looked up with DNS when in deferred mode, many necessary policy checks should not be performed (such as access database lookups) because the true hostname might not be known. These rules cause those checks to be skipped when in deferred mode. Later, when the message is processed from the queue, the hostname will be looked up with DNS.

Because it is unlikely that the sendmail daemon will be run with DeliveryMode=d set in the configuration file, there is no need to prefix ${deliveryMode} with an ampersand in the first rule. We did so here because “good style” says to always use the ampersand.

The ${deliveryMode} macro is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail.

${dsn_envid}

The DSN ENVID= value V8.10 and later

When sendmail receives a message via SMTP, it can also receive an envelope identifier as part of the envelope sender declaration:

MAIL From:<address> ENVID=envelopeID

Here, the MAIL From: command specifies the envelope sender’s address. Following that address is the keyword ENVID= followed by the envelope identifier. Whenever this identifier is presented and accepted, sendmail will place a copy of the identifier into this ${dsn_envid} macro.

A badly formed identifier (one that is not properly xtext-encoded, Macro Xtext Translations on page 795) will be rejected with:

501 5.5.4 Syntax error in ENVID parameter value

For a more complete explanation of the ENVID= keyword, see the ${envid} macro in ${envid} on page 823. Note that this ${dsn_envid} macro is set when mail is received via SMTP and when the -V command-line switch (-V on page 249) is used to set the envelope identifier. By contrast, the ${envid} macro is set only during delivery.

Note that the envelope ID described here is different from the message ID (as used with the Message-Id: header, Message-ID: on page 1159) and different from the queue ID (which identifies a queued file, The Queue Identifier on page 396).

One possible use for this ${dsn_envid} macro might be to syslog the envelope identifier. Another possible use might be to include a header showing the envelope identifier. Consider these mc configuration lines that do the latter:

LOCAL_CONFIG
H?${dsn_envid}?X-DSN-ENVID: ${dsn_envid}
C{persistentMacros} {dsn_envid}

Under V8.12 and later sendmail, the X-DSN-ENVID: header in the preceding example will be included only if the message was received with an envelope identifier that caused the ${dsn_envid} macro to have a value. The C line in the preceding example adds the name {dsn_envid} to the $={persistentMacros} class. Without this line, the value in the ${dsn_envid} macro would not survive queueing.

${dsn_envid} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{dsn_envid}, not ${dsn_envid}), but a $& prefix is not necessary in header definitions.

${dsn_notify}

The DSN NOTIFY= value V8.10 and later

When sendmail receives a message via SMTP, it can also receive information about how it should handle a bounce. That information is included as part of an sender declaration:

RCPT To:<address> NOTIFY=how

Here, the SMTP RCPT To: command specifies an envelope recipient’s address. Following that address is the keyword NOTIFY=, followed by one or more of four possible keywords: success, failure, never, and delay (see -N on page 244 for a more complete description of NOTIFY= and its keywords).

The keywords specified are made the value of the ${dsn_notify} macro. If no NOTIFY= is specified, the ${dsn_notify} macro is undefined (NULL). If multiple RCPT To: commands are issued during a single SMTP session, each command will update the ${dsn_notify} macro in turn, overwriting the prior RCPT To: command’s value.

The ${dsn_notify} macro is also given a value if the -N command-line switch (-N on page 244) is used to set the NOTIFY= keyword during mail submission.

One use for this ${dsn_notify} macro might be to log every instance when notification of success is requested. One way to do this is with a syslog map in the check_compat rule set:

LOCAL_CONFIG
Klog syslog -D -LNOTICE

LOCAL_RULESETS
Scheck_compat
R$*                     $: $&{dsn_notify} $| $1
Rsuccess $| $* $| $*    $: $(log dsn=success, recipient=$2, sender=$1 $)

Here, we declare a syslog map (syslog on page 939) with the K configuration command (The K Configuration Command on page 882) in the LOCAL_CONFIG part of your mc file. The -D tells sendmail to not syslog if the message is being deferred. The -L configuration command tells sendmail to syslog at level LOG_NOTICE (syslog(3) on page 514).

The LOCAL_RULESETS part of your mc file declares the check_compat (The check_compat Rule Set on page 259) rule set, which is called just after the check for too large a size (as defined by M=, M= on page 746). The workspace passed to check_compat is the sender and recipient addresses separated by a $| operator. The first rule simply places the value in the ${dsn_notify} macro at the beginning of the workspace and separates that value from the rest of the workspace with another $| operator.

The second rule looks for the success keyword. If it is found, the log map is called to syslog the three pieces of information shown.

${dsn_notify} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{dsn_notify}, not ${dsn_notify}).

${dsn_ret}

The DSN RET= value V8.10 and later

When sendmail receives a message via SMTP, it can also receive information about how it should handle a bounce. That information is included as part of an envelope-sender declaration:

RCPT To:<address> NOTIFY=how

Here, the RCPT To: command specifies an envelope recipient’s address. Following that address is the keyword RET=, followed by one of two possible keywords: full or hdrs (see -R on page 247 for a more complete description of RET= and its keywords). The full says to return the entire message, header and body, if the message bounces. The hdrs says to return only the header if the message bounces.

When a RET= value is received as part of an SMTP transaction, sendmail saves a copy of the keywords specified in the ${dsn_ret} macro. If multiple RCPT To: commands are issued during a single SMTP session, and each command lists a RET= value, each command will update the ${dsn_ret} macro in turn, overwriting the prior RCPT To: command’s value.

The ${dsn_ret} macro is also given a value if the -R command-line switch (-R on page 247) is used to set the RET= value during mail submission.

For two examples of how this macro might be used in rule sets, see the ${dsn_notify} and ${dsn_envid} macros explained earlier.

${dsn_ret} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{dsn_ret}, not ${dsn_ret}).

$D

The local domain Unused

The $D macro is intended to hold as its value the name of the local domain. It is currently unused.

$e

The SMTP greeting message V8.6 and earlier

Prior to V8.7 sendmail, the $e macro was used to hold the SMTP greeting message. That role has been taken over by the SmtpGreetingMessage option. See SmtpGreetingMessage on page 1093 for a description of both this $e macro and that option.

${envid}

The original DSN envelope ID V8.8 and later

RFC1891 specifies that the keyword ENVID can be given to the MAIL From: command:

MAIL From:<address> ENVID=envelopeID

ENVID is used to propagate a consistent envelope identifier (distinct from the Message-ID: header; see Message-ID: on page 1159) that will be permanently associated with the message. The envelopeID can contain any ASCII characters between ! and ~, except + and =. Any characters outside that range must be encoded by prefixing an uppercase, two-digit, hexadecimal representation of it with a plus sign. For example, an envelopeID composed of the letter X followed by a delete character would be encoded like this:

X+7F

When mail is received over an SMTP channel and an ENVID identifier is specified, that identifier is saved as part of the envelope information. The value of the ENVID identifier is saved in and restored from the qf file’s Z line (Z line on page 458). For bounced mail, the ENVID identifier is printed with the Original-Envelope-Id: DSN header (see RFC1894) as part of the DSN MIME body. Beginning with V8.8 sendmail, an ENVID identifier can also be assigned to a message with the -V command-line switch (-V on page 249).

The ${envid} macro is set only during delivery. By contrast, the ${dsn_envid} macro (${dsn_envid} on page 820) is set when mail is received via SMTP and when the -V command-line switch (-V on page 249) is used to set the envelope identifier.

When mail is delivered, the value of the envelope’s ENVID identifier is saved in the ${envid} macro. That macro is available for use with delivery agents that understand DSN.

${envid} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{envid}, not ${envid}).

$E

The X.400 relay mc configuration

The $E macro is reserved for the future use of the mc technique. It will be used to hold the name of the X.400 relay.

$f

The sender’s address All versions

The $f macro is used to hold the address of the sender. That address can be obtained by sendmail from any of a variety of places:

  • During an SMTP conversation the sending host specifies the address of the sender by issuing a MAIL From: command.

  • Users and programs can specify the address of the sender by using the -f command-line switch when running sendmail.

  • In processing a message from the queue, the sender’s address is taken from the qf file’s S line.

  • In processing bounced mail, the sender becomes the name specified by the value of $n, usually mailer-daemon.

  • In the absence of the preceding factors, sendmail tries to use the user identity of the invoking program to determine the sender.

Once sendmail has determined the sender (and performed aliasing for a local sender), it rewrites the address found with the canonify rule set 3, the rule set 1, and the final rule set 4. The rewritten address is then made the value of $f.

$f is intended for use in both configuration-file header commands and delivery agent A= equates. $f differs from $g in that $g undergoes additional processing to produce a true return address. When sendmail queues a mail message and when it processes the queue, the values in $f and $g are identical.

$f is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&f, not $f).

$F

The fax relay mc configuration

The $F macro defines the machine to use as the fax relay. You should never use this macro directly because it might change in a future release of sendmail. Use the FAX_RELAY mc configuration macro instead (FAX_RELAY mc Macro on page 604).

$g

The sender’s address relative to recipient All versions

The $g macro is identical to $f except that it undergoes additional rule-set processing to translate it into a full return address. During delivery the sender’s address is processed by the canonify rule set 3, the rule set 1, and the final rule set 4, and then placed into $f. That rewritten address is further processed by the canonify rule set 3 and rule set 1 again, then rewritten by the rule set specified in the S= equate of the delivery agent. Finally, it is rewritten by the final rule set 4, and the result is placed into $g.

$g holds the official return address for the sender. As such, it should be used in the From: and Return-Path: header definitions.

The S= equate for each delivery agent must perform all necessary translations to produce a value for $g that is correct. Because the form of a correct return address varies depending on the delivery agent, other rule sets should generally not be used for this translation.

Ordinarily, RFC2822 comments (Comments in the Header Field on page 1125) are restored when $g is used in headers. To omit those comments (perhaps for security reasons) you can use the F=c delivery agent flag (F=c on page 768).

$g is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&g, not $g).

$h

Host part of the delivery agent triple All versions

The parse rule set 0 (The parse Rule Set 0 on page 696) is used to resolve the recipient address into a triple: the delivery agent (with $#), the host part of the address (with $@), and the recipient address (with $:). The host part, from the $@, is made the value of $h. Once $h’s value has been set, it undergoes no further rule-set parsing.

$h is intended for use in the A= equate (A= on page 738) of delivery agent definitions. Normally, it is converted to all lowercase before use, but that conversion can be suppressed with the F=h delivery agent flag (F=h on page 772).

$h is also used by the localaddr rule set 5 (The localaddr Rule Set 5 on page 700) to process +detail addresses (Plussed Detail Addressing on page 476).

$h is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&h, not $h).

${hdr_name}

The current header’s name V8.10 and later

When a header screening rule set is defined using the H configuration command’s * in place of the header’s name:

H*:     $>CheckBanned

the header that caused the CheckBanned rule set to be called is not passed in the CheckBanned rule set’s workspace. To make design of such rules possible, sendmail offers this ${hdr_name} macro. It contains as its value the current name of the header being processed. The name is stored without a colon. One example of a use for this macro can be seen in H* a Default for All Headers on page 1134.

${hdr_name} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{hdr_name}, not ${hdr_name}).

${hdrlen}

The length of ${currHeader} V8.10 and later

When a header is checked using the $>+ in an H configuration command (Use $>+ to Include RFC2822 Comments on page 1131) the unaltered value of the header is stored in the ${currHeader} macro and the length of that header’s unaltered value is stored in this ${hdrlen} macro. Note that the value stored in ${currHeader} will be truncated to MAXNAME (MAX... on page 120) characters, the default for which is 256. If the header’s value was longer than MAXNAME characters, the number of characters stored in ${currHeader} will differ from the value stored in ${hdrlen}. For an illustration of one way to use this macro, see Check the header’s length on page 1134.

${hdrlen} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{hdrlen}, not ${hdrlen}).

$H

The mail hub mc configuration

The m4 FEATURE(nullclient) (FEATURE(nullclient) on page 637) causes all mail to be sent to a central hub machine for handling. Part of what it does is to define the mc macro MAIL_HUB:

define(`MAIL_HUB', `hub')dnl

This also causes $H to be defined as hub. If MAIL_HUB has a value, and if LOCAL_RELAY ($R on page 843) does not, all local email is forwarded to hub. If LOCAL_RELAY is defined, it takes precedence over MAIL_HUB for some mail. See MAIL_HUB mc Macro on page 605 for a description of MAIL_HUB and how it interacts with LOCAL_RELAY.

You should never use this macro directly, because it might change in a future release of sendmail. Use the MAIL_HUB mc configuration macro instead.

$i

The queue identifier All versions

Each queued message is identified by a unique identifier (The Queue Identifier on page 396). The $i macro contains as its value that identifier. Prior to V8.6 sendmail, $i had a value assigned to it only when a file was first placed into the queue. Beginning with V8.6 sendmail, $i is also given a value when the queue file is processed.

$i is not used by sendmail internally, nor should you use it in a rule set. It should be trusted for use only in the Received: and Message-ID: headers.

${if_addr}

The IP address of the receive interface V8.10 and later

When sendmail first starts up as a listening daemon, it binds to a port on all interfaces or on a particular interface (DaemonPortOptions=Addr= on page 994). It then waits to accept connections from hosts or programs that wish to route mail through it. Those hosts or programs are called “clients,” and when they initiate a connection, it is called a client connection.

When a client connects to the local machine, sendmail records the local IP address of the connected-to interface in this ${if_addr} macro. If the address is an IPv4 address, the value stored is just the address:

123.45.67.8

But if the address is an IPv6 address, the address stored is prefixed with a literal IPv6:. For example:

IPv6:3ffe:8050:201:1860:42::1

If the connection was made on the loopback interface, the ${if_addr} macro is undefined.

${if_addr} is available for use in rule sets, and can be useful for rejecting spam or restricting access to a list of particular addresses. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{if_addr}, not ${if_addr}).

${if_addr} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail.

${if_addr_out}

The IP address of the send interface V8.12 and later

The sendmail program can send SMTP email over one or more network interfaces, where each interface can have one or more addresses associated with it. When sendmail sends a network email message, it begins by connecting to a host on the network. Once that connection has been made (once the other site accepts the connection), sendmail records the address associated with the interface over which it made that outbound connection in the ${if_addr_out} macro.

If the connection uses an interface with an IPv4 address, that IP address is stored as, for example:

123.45.67.8

If the connection uses an interface with an IPv6 address, the address stored is prefixed with a literal IPv6:. For example:

IPv6:3ffe:8050:201:1860:42::1

If the connection uses the loopback interface, the value stored in ${if_addr_out} is 127.0.0.1 for IPv4, and IPv6:::1 for IPv6.

${if_addr_out} is available for use in rule sets, and can be useful for rejecting spam or restricting connections to particular addresses. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{if_addr_out}, not ${if_addr_out}).

${if_addr_out} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail.

${if_family}

The network family of the receive interface V8.10 and later

When sendmail first starts up as a listening daemon, it binds to a port on all interfaces or on a particular interface (DaemonPortOptions=Addr= on page 994). It then waits to accept connections from hosts or programs that wish to route mail through it. Those hosts or programs are called “clients,” and when they initiate a connection, it is called a client connection.

When a client connects to the local machine, sendmail records the local IP address of the connected-to interface in the ${if_addr} macro (as described earlier) and the family of that address in this ${if_family} macro. The family is a text representation of the integer value that represents the family, as defined in sys/socket.h. If the connection is from the local host, the ${if_family} macro is undefined. A value of 2, for example, could represent the AF_INET family.

${if_family} is available for use in rule sets, and can be useful for rejecting spam or restricting connections to particular addresses. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{if_family}, not ${if_family}).

${if_family} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail.

${if_family_out}

The network family of the send interface V8.12 and later

The sendmail program can send SMTP email over one or more network interfaces, where each interface can have one or more addresses associated with it. When sendmail sends a network email message, it begins by connecting to a host on the network. Once that connection has been made (once the other site accepts the connection), sendmail records in the ${if_addr_out} macro the address associated with the interface over which it made that outbound connection. It then records the family to which that address belongs in the ${if_family_out} macro. The family is a text representation of an integer value that represents the family, as defined in sys/socket.h. A value of 2, for example, could represent the AF_INET family.

${if_family_out} is available for use in rule sets, and can be useful for rejecting spam or restricting connections to particular addresses. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{if_family_out}, not ${if_family_out}).

${if_family_out} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail.

${if_name}

The name of the receive interface V8.10 and later

Network interfaces can have one or more addresses associated with each interface, and each address will have a hostname associated with it. For example, on a machine with two interfaces, the one connected to the outside world might have the name host.your.domain, whereas the interface that is connected to the internal network might have the name host.sub.your.domain.

When sendmail first starts up as a listening daemon, it binds to a port on all interfaces or on a particular interface (DaemonPortOptions=Addr= on page 994). It then waits to accept connections from hosts or programs (clients) that wish to route mail through it.

When a client connects to the local machine, sendmail records the local IP address of the connected-to interface in the ${if_addr} macro (${if_addr} on page 827), the family of that address in the ${if_family} macro (${if_family} on page 828), and the name associated with the interface over which the connection was made in this ${if_name} macro. If the connection is on the local host’s loopback interface, the ${if_name} macro is undefined.

The ${if_name} macro can be useful when you are set up to do virtual hosting. You can have sendmail give its greeting message in a form that makes it appear to be the host that is associated with the interface:

LOCAL_CONFIG
define(`confSMTP_LOGIN_MSG', `$?{if_name}${if_name}$|$j$. ESMTP MTA')

Here, we define sendmail’s initial greeting message with the SmtpGreetingMessage option (SmtpGreetingMessage on page 1093). It has one of two forms, depending on whether the ${if_name} contains a value. The conditional macro $? looks up the value in ${if_name}. If that value is non-NULL, the value in ${if_name} is printed. Otherwise, the canonical local host name (the $|) is printed (the $j). The $. terminates the if test, and a literal ESMTP MTA is always printed:

220 virtual.domain ESMTP MTA        ← the outside interface
220 host.your.domain ESMTP MTA      ← the loopback interface

${if_name} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{if_name}, not ${if_name}).

${if_name_out}

The name of the send interface V8.12 and later

Network interfaces can have one or more addresses associated with each interface, and each address will have a hostname associated with it. For example, on a machine with two interfaces, the one connected to the outside world might have the name host.your.domain, whereas the interface that is connected to the internal network might have the name host.sub.your.domain.

When sendmail sends a network email message, it begins by connecting to a host on the network. Once that connection has been made (once the other site accepts the connection) sendmail records in the ${if_addr_out} macro the hostname associated with the local interface over which the outbound connection was made.

The ${if_name_out} macro is useful with the syslog database map (syslog on page 939) for logging which interface was used to send messages. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{if_name_out}, not ${if_name_out}).

${if_name_out} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail.

$j

Our official canonical name All versions

The $j macro is used to hold the fully qualified domain name of the local machine. V8 sendmail automatically defines $j to be the fully qualified canonical name of the local host.[319] However, you can still redefine $j if necessary—for example, if sendmail cannot figure out your fully qualified canonical name, or if your machine has multiple network interfaces and sendmail chooses the name associated with the wrong interface.

A fully qualified domain name is one that begins with the local hostname, which is followed by a dot and all the components of the local domain.

The hostname part is the name of the local machine. That name is defined at boot time in ways that vary with the version of Unix you are using.

The local domain refers to the DNS domain, not to the NIS domain. If DNS is running, the domain is defined in the /etc/resolv.conf file. For example:

domain wash.dc.gov

At many sites, the local hostname is already fully qualified. To tell whether your site uses just the local hostname, run sendmail with a -d0.4 switch:

% /usr/sbin/sendmail -d0.4 -bt < /dev/null
canonical name: wash            ← not fully qualified (and wrong!)
canonical name: wash.dc.gov     ← fully qualified (correct)

The $j macro is used in two ways by sendmail. Because $j holds the fully qualified domain name, sendmail uses that name to avoid making SMTP connections to itself. It also uses that name in all phases of SMTP conversations that require the local machine’s identity. One indication of an improperly formed $j is the following SMTP error:

553 5.0.0 wash.dc.gov.dc.gov hostname configuration error

Here, $j was wrongly defined by adding the local domain to a $w that already included that domain:

# Our domain
DDdc.gov
# Our fully qualified name
Dj$w.$D

One way to tell whether $j contains the correct value is to send mail to yourself. Examine the Received: headers. The name of the local host must be fully qualified where it appears in them:

Received: by wash.dc.gov    ...other text heremust be a fully qualified domain name

$j is also used in the Message-ID: header definition.

The $j macro must never be defined in the command line. $j must appear at the beginning of the definition of the SmtpGreetingMessage option (formerly $e, SmtpGreetingMessage on page 1093).

Beginning with V8.7, and in the rare event that you need to give $j a value, you can do so in your mc configuration file like this:

dnl Here at your.domain we hardwire the domain.
define(`confDOMAIN_NAME', `your.domain')

$k

Our UUCP node name V8.1 and later

The UUCP suite of software gets the name of the local host from the uname(2) system call, whereas sendmail gets the name of the local host from the gethostbyname(3) or getipnodebyname(3) system call. For sendmail to easily handle UUCP addresses, V8 sendmail also makes use of the uname(2) function.

First the host part of the fully qualified name returned by gethostbyname(3) or getipnodebyname(3) is saved as the first string in the class $=w. Then uname(2) is called. If the call succeeds, the macro $k and the class $=k are both given the nodename value returned. If the call fails, both are given the same hostname value that was given to the $j. If the system does not have uname(2) available (if HASUNAME was not defined when sendmail was compiled; see HAS... on page 114), sendmail simulates it. The sendmail program’s internal replacement for uname begins by reading /etc/whoami. If that file does not exist or cannot be read, sendmail scans /usr/include/whoami.h for a line beginning with the #define sysname. If that fails and if pre-V8.10 sendmail was compiled with TRUST_POPEN[320] defined, sendmail executes the following command and reads its output as the UUCP node name:

uname -l

If all these fail, $k is set to be the same as $j.

$k is assigned its value when sendmail first begins to run. It can be given a new value either in the configuration file or from the command line. Because $k does not change once it is defined, you need not prefix it with $& when using it in rules.

$l (lowercase L)

The Unix From format V8.6 and earlier

Prior to V8.7 sendmail, the $l macro was used to define the appearance of the five-character "From" header, and the format of the line that was used to separate one message from another in a file of many mail messages. This role has been assumed by the UnixFromLine option. See UnixFromLine on page 1113 for a description of both this $l macro and that new option.

${load_avg}

The current load average V8.10 and later

The ${load_avg} macro contains as its value the current one-minute load average of the machine on which sendmail is running. That value is a rounded integer representation of a possible floating-point value.

One use for this ${load_avg} sendmail macro might be to reject SMTP ETRN commands when the load average it too high:

LOCAL_CONFIG
D{OurETRNlimit}5
Karith math

LOCAL_RULESETS
Scheck_etrn
R $*             $: $(math l $@ $&{load_avg} $@ ${OurETRNlimit} $)
R FALSE          $# error $@ 4.7.1 $: "450 The load average is currently too high."

Here, we add two new sections to our mc configuration file. The first, under LOCAL_CONFIG, defines a sendmail macro, ${OurETRNlimit}, that will hold as its value the limit we have set to reject ERTN commands. In this mc section, we also defined a database map of type arith (arith on page 898).

In the second section, following the LOCAL_RULESETS, we declare the check_etrn rule set (check_etrn on page 706). That rule set is called from inside sendmail (just after an SMTP ETRN command is received, but before the reply to that command is sent) and can determine whether the SMTP ETRN command should be allowed. If the rule set returns the $#error delivery agent, the SMTP ETRN command is denied. Otherwise, it is allowed.

The first rule matches anything in the LHS, then ignores that value in the RHS. The RHS looks up the current ($&) value of the ${load_avg} macro, then uses the math database map to compare that value to the limit set in our ${OurETRNlimit} macro. If the load average is greater than or equal to our limit, the database map returns a literal FALSE.

The second rule detects a literal FALSE and uses an RHS selection of the $#error delivery agent to reject the ERTN command.

${load_avg} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{load_avg}, not ${load_avg}).

$L

The unknown local user relay mc configuration

The $L macro is used by the LUSER_RELAY mc configuration macro (LUSER_RELAY mc Macro on page 605) to store the hostname that will handle local-looking names that are not local. Do not use this $L macro directly, because it might change in a future release of sendmail.

$m

The DNS domain name V8.1 and later

Under V8 sendmail,[321] the $m macro is used to store the domain part of the local host’s fully qualified name. A fully qualified name begins with the local hostname, followed by a dot and all the components of the local DNS domain.

When V8 sendmail first starts to run, it calls gethostname(3) to get the name of the local machine. If that call fails, it sets that local name to be localhost. Then sendmail calls gethostbyname(3) or getipnodebyname(3) to find the official name for the local host. It then looks for the leftmost dot in the official name, and if it finds one, everything from the first character following that dot to the end of the name then becomes the value for $m:

host.domain
     ↑
     domain part made the value of $m

$m is initialized before the configuration file is read. Consequently, it can be redefined in the configuration file or as a part of the command line. Because $m generally does not change once it is defined, you need not prefix it with $& when using it in rules.

${mail_addr}

Saved $: value for MAIL From: triple V8.10 and later

Upon receipt of the MAIL From: address, a delivery agent is selected by the RHS of a parse rule set 0 rule, which defines a triple that contains three pieces of information for that address:

$#delivery_agent $@ host  $:address

The $: portion of the triple contains the address part of the information with any commentary removed. For example:

gw@wash.dc.gov

Once that address is determined for the $: part of the triple, that address is copied to this ${mail_addr} macro.

${mail_addr} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{mail_addr}, not ${mail_addr}).

${mail_host}

Saved $@ value for MAIL From: triple V8.10 and later

Upon receipt of the MAIL From: address, a delivery agent is selected by the RHS of a parse rule set 0 rule, which defines a triple that contains three pieces of information for that address:

$#delivery_agent $@ host  $:address

The $@ portion of the triple contains the host to which to connect for delivery. For example:

wash.dc.gov

Once that host is determined for the $@ part of the triple, it is copied to this ${mail_host} macro.

${mail_host} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{mail_host}, not ${mail_host}).

${mail_mailer}

Saved $# value for MAIL From: triple V8.10 and later

Upon receipt of the MAIL From: address, a delivery agent is selected by the RHS of a parse rule set 0 rule, which defines a triple that contains three pieces of information for that address:

$#delivery_agent $@ host  $:address

The $# portion of the triple specifies the delivery agent to use for delivery. For example:

esmtp

Once that delivery agent is determined for the $# part of the triple, it is copied to this ${mail_mailer} sendmail macro.

${mail_mailer} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{mail_mailer}, not ${mail_mailer}).

${msg_id}

Value of the Message-Id: header V8.13 and later

The Message-Id: header (Message-ID: on page 1159) is used to uniquely identify each mail message. It must be declared in the configuration file. Its field must be an expression in the syntax of a legal email address (user@host) enclosed in angle brackets (< and >) composed of elements that create an identifier that is truly unique worldwide.

Beginning with V8.13, when sendmail finds a Message-Id: header in the current message, it assigns the value for that header to this ${msg_id} macro. If sendmail finds no Message-Id: header, it creates one and assigns that new value to this ${msg_id} macro.

If a Message-Id: header appeared in the original inbound message, its value can be made available to rule sets by using the H configuration command (Rules Check Header Contents on page 1130) and to Milters using an xxfi_header() routine (Milter xxfi_header() on page 1217). But if sendmail creates the Message-Id: header, its value can be made available only by using this ${msg_id} macro.

Be aware that ${msg_id} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{msg_id}, not ${msg_id}).

${msg_size}

Size of the current message V8.10 and later

The size of a message is considered to be the number of bytes in its headers and body. That size can be declared or calculated. It is predeclared with the SIZE= MAIL From: ESMTP parameter:

MAIL From:<liu@td.co.jp> SIZE=45621

Immediately after sendmail reads the size value from the SIZE= parameter, it stores that value in the ${msg_size} macro. The value is stored before checks for validity are made and so can contain nonnumeric characters. If the message lacks a SIZE= parameter, the ${msg_size} macro will be undefined (NULL).

The message size is calculated again after the entire message has been read (either from standard input, the queue, or via SMTP) and the value in ${msg_size} is updated with that new value. If an external Milter program (Create Milter Support on page 1170) is called, the ${msg_size} is updated again because that program might have changed the size of the message.

The ${msg_size} macro can be useful in the check_data rule set (check_data on page 705) which is called just after the SMTP DATA command and can be used to check the size specified with SIZE=. It can also be useful in the check_compat rule set (The check_compat Rule Set on page 259) which is called just before delivery and can be used to check the size of the received message.

${msg_size} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{msg_size}, not ${msg_size}).

$M

Whom we are masquerading as mc configuration

When you define MASQUERADE_AS using the m4 configuration technique, you both enable masquerading (MASQUERADE_AS mc Macro on page 600) and assign the masquerade-as hostname to this $M macro. Note that defining $M will not enable masquerading. You must use the MASQUERADE_AS m4 configuration command to enable this service.

You should never use this macro directly because it might change in a future release of sendmail. Use the MASQUERADE_AS mc configuration macro instead.

${MTAHost}

Host for the msp feature V8.12 and later

The FEATURE(msp) can take an optional argument. That argument determines whether the mail collected by the MSP invocation of sendmail should be delivered to the local machine or to another machine:

FEATURE(`msp')                  ← deliver to localhost
FEATURE(`msp', `otherhost')     ← deliver to otherhost

If this optional argument is given to FEATURE(msp), that argument is assigned to the ${MTAHost} macro. If this optional argument is absent, the value assigned to ${MTAHost} is [localhost]. The square brackets around localhost suppress the lookup of MX records.

All messages will be forwarded to the ${MTAHost}. If you wish to suppress MX lookups for the ${MTAHost} host, surround the hostname with square brackets when you declare it with FEATURE(msp):

FEATURE(`msp', `[otherhost]')

See Install sendmail on page 60 for a description of how to install an MSP server, and FEATURE(msp) on page 633 for a description of FEATURE(msp).

You should never use this ${MTAHost} macro directly, because it might change in a future release of sendmail. Use FEATURE(msp) instead.

$n

The error message sender All versions

The $n macro contains the name of the person who returns failed mail. Traditionally, that value is the name MAILER-DAEMON.

When delivery fails, notification of that failure is sent to the originating sender. The sendmail program generates a new message header, where the sender of the error mail message (and the sender in the envelope) is taken from $n. Then, sendmail includes the original header and all error information in the body, but might or might not include the original body in the bounce message (-R on page 247).

The $n macro must contain either a real user’s name or a name that resolves to a real user through aliasing. If sendmail cannot resolve $n to a real user, the following message is logged:

Can't parse myself!

and the returned error mail message is saved in the file defined by the DeadLetterDrop option (DeadLetterDrop on page 998) if that option is defined. Otherwise, sendmail converts the qf file into a Qf file (Bogus qf Files on page 419).

When an error mail message is sent, $f ($f on page 824) is given the value of $n. Prior to V8.7, $n must be defined in the configuration file. Beginning with V8.7 sendmail, $n is automatically defined as MAILER-DAEMON when sendmail first starts up.

Beginning with V8.7 sendmail, you can redefine $n in your mc configuration file with a line such as this:

define(`confMAILER_NAME', `BOUNCER')

But be aware that many software programs view the name MAILER-DAEMON as special. By changing that name, you might break the way bounces are handled on your, or other, machines.

Because $n generally does not change once it is defined, you need not prefix it with $& when using it in rules.

${nbadrcpts}

Number of bad envelope recipients V8.13 and later

When sendmail receives an SMTP RCPT To: command, it examines the recipient address contained in that command, then accepts known local recipients and rejects other recipients. If relaying is enabled for selected hosts, envelope recipients addressed to those hosts are also allowed. If the address is disallowed, the message is rejected by sendmail and neither rule sets nor Milters ever see it.

If knowing the number of rejected recipients for a given envelope is important to you, you may access that number using this ${nbadrcpts} macro.

If used in rule sets, the ${nbadrcpts} macro will contain only a true total after all envelope recipients have been processed. Thus, a good place to use it might be in the check_data rule set (check_data on page 705) which is called after the SMTP DATA command is received, but before that command is acknowledged (in other words, after all recipients have been processed):

LOCAL_RULESETS
Scheck_data
R $*                     $: $&{nbadrcpts}
R $+                     $: $(arith l $@ $1 $@ 25 $)
R FALSE            $# error $@ 5.1.2 $: "553 Too many bad recipients"

Here, under the LOCAL_RULESETS portion of your mc configuration file, you first declare the check_data rule set, which contains three rules. The first rule simply matches anything on the LHS (the $*) and places the value of this ${nbadrcpts} macro into the workspace. The second rule compares that value (using the arith database map; see arith on page 898) to the literal value 25. If the test fails (if there are 25 or more bad envelope recipients) the second rule returns FALSE (in the workspace) and the message is rejected using the third rule.

Note that this ${nbadrcpts} macro can also be used by Milters, but remember that it is reliable only if you fetch its value after all envelope recipients have been processed. You may add this macro to those passed to your Milter with a line like the following in your mc configuration file:

define(`confMILTER_MACROS_EOM', confMILTER_MACROS_EOM``, {nbadrcpts}'')

Also note that the two single quotes are necessary because the second argument to the define command contains a comma. This line in your mc configuration file makes the ${nbadrcpts} macro available to your Milters after the entire envelope has been processed, but before the final dot has been acknowledged.

Be aware that ${nbadrcpts} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{nbadrcpts}, not ${nbadrcpts}).

${nrcpts}

Number of envelope recipients V8.9 and later

The recipients of an email message can be specified or added to the message in several ways:

As each recipient is added to the internal list of recipients, sendmail updates the ${nrcpts} macro to reflect the current count.

The ${nrcpts} macro can be useful in the check_compat rule set (The check_compat Rule Set on page 259) which is called just before delivery. The value in ${nrcpts} can be used to check the number of recipients, and to possibly refuse delivery if there are too many recipients. (See also the MaxRecipientsPerMessage option, MaxRecipientsPerMessage on page 1050.)

${nrcpts} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{nrcpts}, not ${nrcpts}).

${ntries}

Number of delivery attempts V8.10 and later

When a message begins life and delivery has not yet been attempted, the message is considered to have had zero delivery attempts. If the first delivery attempt fails, the message is deferred to the queue and marked as having had one delivery attempt. Thereafter, each time the message is fetched from the queue and delivery fails, the number of attempts is incremented. Each time the message is read from the queue, the number of delivery attempts is stored in the ${ntries} macro.

One use for this ${ntries} macro might be to bounce high-priority mail that fails on the first try. If it cannot be sent right away, perhaps such mail should be faxed, or followed up with a telephone call. Consider the following mc file lines that suggest one way to accomplish this:

LOCAL_CONFIG
C{persistentMacros} {X-Notice}
HX-Notice: $>CheckNotice
Kstore macro

LOCAL_RULESETS
SCheckNotice
R $*           $: $(store {X-Notice} $@ YES $)

Scheck_compat
R $*           $: $&{X-Notice}
R $*           $: $(store {X-Notice} $) $1
R YES          $: $(math l $@ $&{ntries} $@ 1 $)
R FALSE        $#error $@ 5.7.1 $: "550 X-Notice mail exceeded allowed tries"

Here, we set up our own ${X-Notice} macro as a private flag so that we can detect the presence of the X-Notice: header, even when the message is read from the queue. Under LOCAL_CONFIG, we first add the ${X-Notice} macro to the class $={persistentMacros} ($={persistentMacros} on page 873), which ensures that ${X-Notice} will retain its value despite the message being queued. We then use the H configuration command to define the X-Notice: header and to specify that the X-Notice: header’s value must be processed by the CheckNotice rule set. Finally, we declare a macro-type database map (macro on page 925) which we will reference with the name store.

In the LOCAL_RULESETS section we set up two rule sets. The first rule set is the CheckNotice rule set we referenced with the H configuration command. That rule set contains a single rule which stores a literal YES into the ${X-Notice} macro.

The second rule set is the check_compat rule set (The check_compat Rule Set on page 259) which is called just prior to delivery. It contains four rules. The first rule fetches the current value (the $&) of the ${X-Notice} macro and places that value into the workspace. The second rule clears the ${X-Notice} macro to ready it for any future message. The third rule looks for a literal YES in the workspace, and if found, compares the value in the ${ntries} macro to a one. If ${ntries} is not less than one, a literal FALSE is placed into the workspace. The last rule looks for a literal FALSE in the workspace, and if found, rejects (bounces) the message with an appropriate notice.

${ntries} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{ntries}, not ${ntries}).

$o

Token separation operators V8.6 and earlier

Prior to V8.7, the $o macro stored as its value a sequence of characters, any one of which could be used to separate the components of an address into tokens. That role has been taken over by the V8.7 and later OperatorChars option (OperatorChars on page 1062).

For backward compatibility, the $o macro is still honored by V8.7 sendmail in preversion 7 configuration files (The V Configuration Command on page 580). Otherwise, it is unused in version 7 and later configuration files.

${opMode}

The startup operating mode V8.7 and later

Beginning with V8.7, the ${opMode} holds as its value the operating mode that sendmail was started with. The operating mode is set with the -b command-line switch (-b on page 233). For example, if sendmail were started as a daemon with -bd, the value in ${opMode} would become d.[322]

Once set, ${opMode} retains its initial value as long as sendmail runs. It can be changed only by defining it in the configuration file (not recommended). Currently, ${opMode} is used only in rule sets by FEATURE(redirect) (FEATURE(redirect) on page 640). Because ${opMode} generally does not change once it is defined, you need not prefix it with $& when using it in rules.

$p

The sendmail process id All versions

The p macro contains the process ID of the sendmail that executes the delivery agent. Every process (running program) under Unix has a unique identification number associated with it (a process ID). Process IDs are necessary to differentiate one incantation of a program from another. The sendmail program fork(2)s often to perform tasks (such as delivery) while performing other tasks (such as listening for incoming SMTP connections). All copies share the name sendmail; each has a unique process ID number.

$p is intended for use in header definitions but can also be used in the A= equate (A= on page 738) of delivery agents.

$p is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&p, not $p).

$q

The default format of the sender’s address V8.6 and earlier

Beginning with V8.7 sendmail, the $q macro is no longer used. Instead, sendmail uses the $g and $x macros (see the end of this section).

Prior to V8.7, the $q macro was used to specify the form that the sender’s address would take in header definitions. It was most often used in the From: and Resent-From: header lines.

The definition of $q had to adhere to the standard form of addresses as defined by RFC822. It had to contain just an address or an address and a comment. The traditional definitions of $q were:

Dq<$g>        ← as <george@wash.dc.gov
Dq$g          ← as george@wash.dc.gov

Dq$x <$g>     ← as George Washington <george@wash.dc.gov>
Dq$g ($x)     ← as george@wash.dc.gov (George Washington)

The full name is not always known and so $x can be undefined (empty). As a consequence, when the full name was included in the $q macro definition, it was often wrapped in a conditional test:

Dq$g$?x ($x)$.
Dq$?x$x $.<$g>

Prior to V8.7, $q had to be defined in the configuration file because it was used to define the fields of the Resent-From: and From: headers (From: on page 1157).

Beginning with V8.7 sendmail, those headers are defined by using the $g and $x macros directly. For example:

H?F?Resent-From: $?x$x <$g>$|$g$.
H?F?From: $?x$x <$g>$|$g$.

${quarantine}

The reason why envelope was quarantined V8.13 and later

V8.13 introduced queue quarantining (Queue Quarantining on page 438), the process by which envelopes in the queue are marked as being ineligible for delivery. Such quarantined envelopes may then be reviewed manually or automatically.

When a message is quarantined, the reason it was quarantined is stored as the value of this ${quarantine} macro. When it is later read from the queue, the value of the queue file’s q line (The qf file’s quarantine reason: q line on page 444) is again copied into this ${quarantine} macro.

Note that the ${quarantine} macro can also be used to detect whether a message has been quarantined.

${queue_interval}

The interval specified by -q V8.10 and later

When sendmail first starts, the -q command-line switch (Periodically with -q on page 427) tells it how often to process its queues. The form of that command-line switch looks like this:

-qinterval

The interval is an expression composed of numbers and letters that sets the time interval between queue processing runs. The following, for example, sets the interval to be once every 2 hours, 13 minutes, 7 seconds:

-q2h13m7s

In typical installations, the interval is usually expressed only in minutes:

-q15m

When sendmail first starts, it finds the -q command-line switch, then places the interval value into the ${queue_interval} macro. That value is a text expression containing three positions:

hours:minutes:seconds

If the interval is longer than a day, that number of days (and possibly weeks or months) is expressed in hours in the hours position. If any of the three positions is zero, it is expressed as 00. If any of the three positions has a value less than 10, it is zero-padded on the left. For example, a -q0h9m12s would yield this value in the ${queue_interval} macro:

00:09:12

One possible use for this macro might be to cause rules to function differently depending on whether the -q command-line switch contains an interval. Consider, for example, the following mc configuration file lines:

LOCAL_RULESETS
Squeuegroup
R $*                        $: $&{queue_interval} $| $1
R $+ : $+ : $+ $| $*        $@
... select queue groups here

Here, under LOCAL_RULESETS, we declare the queuegroup rule set (Rule Set Queue Group Selection on page 417), which is used to select queue groups for particular addresses. The first rule prefixes the workspace with the value of the ${queue_interval} macro, and a $| operator. The second rule checks the workspace to the left of the $| to see if it looks like a time expression. If it does (if sendmail was run with a -q interval), we skip (the RHS $@) queue group selection.

This scheme allows the same configuration file to be used for two daemons. One will be the initial delivery daemon and will be run without a queue interval. The other will be the queue processing daemon and will run with a queue interval.

${queue_interval} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that ${queue_interval} is defined after the configuration file is read. Therefore, although it won’t change thereafter, a $& prefix is still necessary when you reference it in rules (that is, use $&{queue_interval}, not ${queue_interval}).

$r

The protocol used All versions

The $r macro stores the name of the protocol that is used when a mail message is first received. If mail is received via SMTP or ESMTP, $r is set accordingly. Incoming UUCP mail sets $r to “UUCP” (using the -p switch). With V8.7, bounced mail will now assign $r the value “internal.”

$r is intended for use only in the Received: header definition:

HReceived: $?sfrom $s $.by $j$?r with $r$. id $i

The value in $r is saved to the qf file when the mail message is queued, and it is restored to $r when the queue is later processed.

$r should never be trusted, and should never be used in rules to make policy decisions.

$r is transient. It can be defined on the command line but should not be defined in the configuration file. Under V8, the -p switch (-p on page 246) is the recommended way to assign a value to $r.

Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&r, not $r).

${rcpt_addr}

Saved $: value for RCPT To: triple V8.10 and later

All envelope addresses (sender and recipient) are passed through the parse rule set 0 so that a delivery agent can be selected. Upon receipt of the RCPT To: address, a delivery agent is selected by the RHS of the parse rule set 0, which defines a triple that contains three pieces of information for that address:

$#delivery_agent $@ host  $:address

The $: portion of the triple contains the address part of the information with any commentary removed. For example:

user@your.domain

Once that address is determined for the $: part of the delivery agent triple, it is copied to this ${rcpt_addr} macro.

${rcpt_addr} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{rcpt_addr}, not ${rcpt_addr}).

${rcpt_host}

Saved $@ value for RCPT To: triple V8.10 and later

All envelope addresses (sender and recipient) are passed through the parse rule set 0 so that a delivery agent can be selected. Upon receipt of the RCPT To: address, a delivery agent is selected by the RHS of the parse rule set 0, which defines a triple that contains three pieces of information for that address:

$#delivery_agent $@ host  $:address

The $@ portion of the triple contains the host to which to connect for delivery. For example:

your.domain

Once that host is determined for the $@ part of the delivery agent triple, it is copied to this ${rcpt_host} macro. For some local delivery agents, this ${rcpt_host} macro can be undefined (NULL).

${rcpt_host} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{rcpt_host}, not ${rcpt_host}).

${rcpt_mailer}

Saved $# value for RCPT To: triple V8.10 and later

All envelope addresses (sender and recipient) are passed through the parse rule set 0 so that a delivery agent can be selected. Upon receipt of the RCPT To: address, a delivery agent is selected by the RHS of the parse rule set 0, which defines a triple that contains three pieces of information for that address:

$#delivery_agent $@ host  $:address

The $# portion of the triple specifies the delivery agent to use for delivery. For example:

local

Once that delivery agent is determined for the $# part of the delivery agent triple, it is copied to this ${rcpt_mailer} macro.

${rcpt_mailer} is transient. If it is defined in the configuration file or in the command line, that definition may be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{rcpt_mailer}, not ${rcpt_mailer}).

$R

The relay for unqualified names mc configuration, deprecated

Using the mc configuration technique, the $R macro stores the hostname defined by LOCAL_RELAY (LOCAL_RELAY mc Macro on page 604). If $H has a value and if $R does not, all local email is forwarded to the hub defined for $H. If $R is defined, it takes precedence over $H for some mail. See MAIL_HUB mc Macro on page 605 for a description of MAIL_HUB and how it interacts with LOCAL_RELAY.

Note that you should not define this $R macro directly, because later versions of sendmail might use a different macro. Instead, use the LOCAL_RELAY mc macro for this purpose.

$s

The sender host’s name All versions

The $s macro contains the name of the sender’s machine (host). $s is given the name of the local host as its value when sendmail starts, unless the -p command-line switch (-p on page 246) is used, in which case $s is given the value specified by that switch. Thereafter, $s is given a new value by sendmail only if the mail message was received via SMTP. For bounced mail, the $s value is always localhost.

The s macro is intended for use in the Received: header definition:

HReceived: $?sfrom $s $.by $j$?r with $r$. id $i

The phrase from host will be included in this header line if $s has any value. Here, host is the name of the sending machine.

The value in $s is saved to the qf file when the mail message is queued and restored to $s when the queue is later processed.

$s is transient. It can be defined on the command line but should not be defined in the configuration file. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&s, not $s).

${sendmailMTACluster}

The LDAP cluster to use V8.12 and later

Beginning with V8.12 sendmail, it is possible to fill a class macro with values from an ldap database map. The general form looks like this:

F{classname}@ldap:switches

The switches are ldap database map-type switches that might look something like this:

-k (&(objectClass=someclass)) -v  classvalue

An alternative form of ldap database map-type declaration uses default switches:

F{classname}@LDAP

Here, the literal @LDAP tells sendmail to use default switches that look like the following (where the line has been split to fit the page):

-k (&(objectClass=sendmailMTAClass)(sendmailMTAClassName=ClassName)
   (|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j)))
   -v sendmailMTAClassValue

Note that the default sendmailMTACluster is based on the value in the ${sendmailMTACluster} macro.

If you plan to use the @LDAP default, you will need to define the ${sendmailMTACluster} macro in your mc configuration file, as for example:

define(`confLDAP_CLUSTER', `clustername')

${sendmailMTACluster} is intended for use only in the default @LDAP setting.

${server_addr}

The address of the connected-to machine V8.11 and later

When sendmail connects to another machine to send email, it gathers two pieces of information about that machine: its name and its IP address. If the connection is over a network, the IP address is stored in this ${server_addr} macro. If the connection is local, as with LMTP, this ${server_addr} macro is given the name of the delivery agent as its value. If neither situation is true, this ${server_addr} macro is given a 0 (a literal zero character) as its value.

The ${server_addr} macro is used chiefly with the authinfo (Authinfo and the access database (V8.12 and later) on page 195), tls_server (The access database with tls_server and tls_client on page 214), and try_tls (Disable STARTTLS with the try_tls rule set on page 217) rule sets.

The ${server_addr} macro is available for your use in rule sets, and can be useful, for example, in policy control. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{server_addr}, not ${server_addr}).

${server_addr} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. ${server_addr} must never be set with the macro database map (macro on page 925) to a value that is empty.

${server_name}

The hostname of the connected-to machine V8.11 and later

When sendmail connects to another machine to send email, it gathers two pieces of information about that machine: its name and its IP address. If the connection is over a network, the host name is stored in this ${server_name} macro. If the connection is local, as with LMTP, this ${server_name} macro is given the name of the delivery agent as its value. If neither situation is true, this ${server_name} macro is given the literal value local.

The ${server_name} macro is used primarily with the authinfo (Authinfo and the access database (V8.12 and later) on page 195), tls_server (The access database with tls_server and tls_client on page 214), and try_tls (Disable STARTTLS with the try_tls rule set on page 217) rule sets.

The ${server_name} macro is available for your use in rule sets, and can be useful, for example, in policy control. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{server_name}, not ${server_name}).

${server_name} is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. ${server_name} must never be set with the macro database map (macro on page 925) to a value that is empty.

$S

The smart host mc configuration

Using the mc configuration method, the $S macro stores the host name defined by SMART_HOST (SMART_HOST mc macro on page 597). The smart host is the name of the host that can deliver all mail that the local host cannot. $S is most often used with UUCP sites to get DNS mail to the outside world. Do not use this $S macro directly, as it might change without notice in a future version of sendmail. Instead, define this value using the mc SMART_HOST configuration macro.

$t

The current date and time in the form YYYYMMDDHHmm All versions

The $t macro contains the current date and time represented as an integer in the form:

YYYYMMDDHHmm

For example, noon of January 13, 2006 would look like this:

200601131200

The value of $t is set in two places:

  • When sendmail first begins to run, it presets several date-oriented macros internally to the date and time it was run. Among those are the $a, $d, $b, and $t macros. This initialization is done after the configuration file is read.

  • Each time a new envelope is created, the $d, $b, and $t macros are given a default that is the current time.

$t is intended for use in configuration-file header definitions. $t is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&t, not $t).

${time}

Current time in time(3) seconds V8.13 and later

The C-language time(3) routine returns an integer value (type time_t) that represents the current time as the number of seconds that have elapsed since January 1, 1970 (00:00:00). The current time is instantiated at three different moments as sendmail processes envelopes:

  • Just after a connection to the server has been accepted, but before the SMTP conversation begins

  • Just as the queue’s qf file is being read

  • Just as a new envelope is being created to handle bounced email

At each of these three moments, an ASCII representation of the current number of elapsed seconds is placed into the ${time} macro. At the same moment, the following other macros are also given the current time but in other formats:

  • $b holds the current time in RFC2822 format.

  • $d holds the current time in Unix ctime(3) format.

  • $t holds the current time to the minute in the format YYYYMMDDhhmm.

Although the ${time} macro is not used in the standard configuration file, it is available to use in rule sets of your own design. It can, for example, be handy for enforcing timeouts on entries when using POP before relay.

Note that ${time} is intended for use in configuration-file header definitions. $t is transient. If it is defined in the configuration file or in the command line, that definition can be ignored by sendmail. Also note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{time}, not ${time}).

${tls_version}

TLS/SSL version V8.11 and later

When a connection is made or received and STARTTLS is initiated, sendmail updates the value of several macros, among which is this ${tls_version} macro.

${tls_version} stores the TLS version used for the connection. The possible versions are text values that include TLSv1, SSLv3, and SSLv2. The ${tls_version} is used in the standard configuration file as part of the definition of the Received: header:

HReceived: $?sfrom $s $.$?_($?s$|from $.$_)
        $.$?{auth_type}(authenticated$?{auth_ssf} bits=${auth_ssf}$.)
        $.by $j ($v/$Z)$?r with $r$. id $i$?{tls_version}
        (version=${tls_version} cipher=${cipher} bits=${cipher_bits}
verify=${verify})$.$?u
        for $u; $|;
        $.$b

If ${tls_version} has a value, the following is included in the Received: header’s text:

(version=${tls_version} cipher=${cipher} bits=${cipher_bits} verify=${verify})

If ${tls_version} lacks a value, the preceding text is not included, meaning that a STARTTLS session was not used.

${tls_version} is transient. If it is defined in the configuration file or in the command line, that definition is ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{tls_version}, not ${tls_version}).

${total_rate}

Total rate of all inbound client connections V8.13 and later

When a host connects to the listening sendmail server, the server forks a child copy of itself to handle the connection. Before forking, the server increments the total count of all connections. That count is then used to update the connection rate over time for all connections.

The rate is measured over an interval defined by the ConnectionRateWindowSize option (ConnectionRateWindowSize on page 989), which defaults to 60 seconds. Note that this total rate (the rate for all connections) differs from the client rate (the rate for a particular connection).

The ${total_rate} macro is not used in the standard configuration file but is available for your use in rule sets of your own design.

If you are interested in knowing the rate of connections from individual clients, see the ${client_rate} macro (${client_rate} on page 814).

${clienttotal_rate_rate} is transient. If it is defined in the configuration file or in the command line, that definition is ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{total_rate}, not ${total_rate}).

$u

Address part of a delivery agent triple All versions

The parse rule set 0 (The parse Rule Set 0 on page 696) is used to resolve the recipient address into a triple: the delivery agent (with $#), the host part of the address (with $@), and the recipient’s address (with $:). The recipient’s address is then processed by rule set 2 (the generic rule set for all recipient addresses), then by the rule set indicated by the R= equate of the delivery agent (the custom recipient address processing), and finally by the final rule set 4 (post-processing for all addresses).

If the delivery agent has the F=A flag set (F=A on page 767), that rewritten recipient’s address is looked up in the aliases file and replaced with its alias if one exists. If it is not replaced and if the F=5 flag (F=5 on page 764) is set, the address is rewritten by the localaddr rule set 5 to possibly pick a new delivery agent and repeat this process.[323]

After aliasing, the rewritten recipient’s address is then assigned to $u. If the delivery agent’s F=w flag (F=w on page 781) is set,[324] the value of $u is then used to look up information about that user with the method defined by the MailboxDatabase option (MailboxDatabase on page 1042).[325] The user’s home directory is made the value of $z, which in turn is used to access the user’s ~/.forward and dead.letter files.

For all delivery agents, the final value of $u can be used as a component of the delivery agent’s A= equate (A= on page 738). For example:

A=uux - $h!rmail ($u)

Note that $u is special (The special case of $u in A= on page 740) in delivery agent A= equates. If it is absent, sendmail speaks SMTP or LMTP. If it is present and the F=m flag (F=m on page 775) is present, the argument containing $u is repeated as many times as there are multiple recipients.

In V8 sendmail, $u is also set to the original recipient (prior to aliasing) while the message headers are first being read. Therefore, the original recipient information is available for use in the Received: header line, but only if there is just a single recipient.

$u is transient. If it is defined in the configuration file or in the command line, that definition is ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&u, not $u).

$U

The UUCP name to override $k mc configuration

When configuring with the mc configuration technique, you can include support for UUCP by using the MAILER(uucp) command (MAILER( ) m4 macro on page 590) in your mc file. With that support, you can override the use of $k ($k on page 831) with a hostname of your choosing when prefixing a string of hosts with the local hostname:

here!lady!sonya!user
↑
insert local hostname here

If $U has a value, its value will be inserted. If it lacks a value, $k will be inserted.

$U can be useful when several hosts provide UUCP services. It can be defined in your DOMAIN( ) file (DOMAIN( ) m4 macro on page 591) as a single name so that all outgoing UUCP mail will appear as though it is from a common host.

$v

The version of sendmail All versions

The v macro contains the current version of the sendmail program, taken from the Version variable that is initialized in version.c of the sendmail source. $v is used in defining the SmtpGreetingMessage ($e) option (SmtpGreetingMessage on page 1093):

O SmtpGreetingMessage=$j Sendmail $v/$Z; $b

in Received: header lines (Received: on page 1162):

$.by $j ($v/$Z)$?r with $r$. id $i$?{tls_version}

and in the Helpfile message (HelpFile on page 1035):

214-2.0.0 This is sendmail version 8.12.7

The value given to $v can vary with the vendor. There is currently no standard for identifying variations on the sendmail program. Clearly, $v cannot contain a true picture, unless your binary is built from the open source distribution.

$v is internally defined when sendmail starts up. It can be redefined in the configuration file or as part of the command line.

${verify}

Result of cert verification V8.11 and later

When a connection is made or received and STARTTLS is negotiated, sendmail updates the value of several macros, among which is this ${verify} macro.

This ${verify} macro stores a text word that describes the result of verification of the presented certificate. Those possible text words are shown in Table 21-10.

Table 21-10. Possible values for ${verify}

Word

Description

FAIL

A certificate was presented but could not be verified.

NONE

STARTTLS has not been performed.

NOT

No certificate was requested.

NO

No certificate was presented.

OK

The verification was successful.

PROTOCOL

A protocol error occurred.

SOFTWARE

The STARTTLS handshake failed (message will be queued).

TEMP

There was a temporary error.

The ${verify} macro is used in the standard configuration file as part of the definition of the Received: header. If ${tls_version} has a value, the following is included in the Received: header’s text:

(version=${tls_version} cipher=${cipher} bits=${cipher_bits} verify=${verify})

If ${tls_version} lacks a value, the preceding text is not included, meaning a STARTTLS connection was not used.

${verify} is transient. If it is defined in the configuration file or in the command line, that definition is ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&{verify}, not ${verify}).

$V

The UUCP relay for class $=V mc configuration

$V holds as its value the name of the host that will handle all UUCP mail for the class $=V. See SITECONFIG mc Macro (Obsolete) on page 609 for a discussion of UUCP relays in general, and how this macro relates to $W, $X, and $Y macros.

$w

The short name of this host All versions

When sendmail first starts to run, it calls gethostname(3) to get the name of the local machine. If that call fails, it sets that local name to be localhost. Then gethostbyname(3) is called to find the official name for the local host. If that call fails, the official name for the local host remains unchanged. The official name for the local host is assigned to $j.

If the V command’s version (The V Configuration Command on page 580) is 5 or higher, V8 sendmail discards the domain and assigns the result to $w (the short name):

here.us.edu
    ↑
    from here to end of name discarded

If the version is 4 or less, $w is assigned the fully qualified name (and is identical to $j).

$w is then appended to class $=w ($=w on page 876). $=w is used internally by sendmail to screen all MX records that are found in delivering mail over the network.[326] Each such record is compared in a case-insensitive fashion to $=w. If there is a match, that MX record and all additional MX records of lower priority are skipped. This prevents sendmail from mistakenly connecting to itself.

Any of the following errors (or variations on them) indicate that $=w, $w, or $j might contain a faulty value, most likely from a bad configuration file declaration:

553 host config error: mail loops back to myself
553 Local configuration error, hostname not recognized as local
553 host hostname configuration error
553 5.3.5 host config error: mail loops back to me (MX problem?)

Note that if $w is pulled from the name server and the host is running BIND, and a cache is being downloaded, $w could be periodically unresolved. In this instance, sendmail sleeps and retries the lookup.

$w is defined when sendmail starts up. It can be redefined in the configuration file or as part of the command line. Once it is defined, $w doesn’t change, so there is no need to prefix it with a $& when using it in rules.

$W

The UUCP relay for class $=W mc configuration

$W holds as its value the name of the host that will handle all UUCP mail for the class $=W. See SITECONFIG mc Macro (Obsolete) on page 609 for a discussion of UUCP relays in general, and how this macro relates to $V, $X, and $Y macros.

$x

The full name of the sender All versions

The $x macro holds the full name of the sender. When sendmail processes a mail message for delivery, it rewrites the sender’s address using the canonify rule set 3 and the parse rule set 0 so that it can determine whether the sender is local. If the sender is local, the parse rule set 0 provides the sender’s login name with the $: operator. Then, if the delivery agent’s F=w flag (F=w on page 781) is set,[327] the login name is looked up using the method defined by the MailboxDatabase option (MailboxDatabase on page 1042).[328] If the login name is known, the sender’s full name is returned. If necessary, that full name is then processed, throwing away phone numbers and the like and converting the & character. The result, usually fairly close to the sender’s actual full name, is the value assigned to the $x macro.

Under certain circumstances, sendmail places a different value in $x:

  • When sendmail first starts to run, it sets the full name to be the value of the NAME environment variable, and places that value into $x.

  • The -F command-line switch (-F on page 240) can overwrite the value in the $x macro.

  • If the operating mode is -q (Periodically with -q on page 427) or -bd (-bd on page 234), the value in $x is reset to NULL.

  • In processing the headers of a message, if sendmail finds a Full-Name: header (Full-Name: on page 1158), it assigns the text of that header to the $x macro.

  • In sending a failed mail message, the login name of the sender is taken from $n, and the full name is set to be:

    Mail Delivery Subsystem

The $x macro is intended for use in various header definitions. $x is transient. If it is defined in the configuration file or the command line, that definition will be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&x, not $x).

$X

The UUCP relay for class $=X mc configuration

$X holds as its value the name of the host that will handle all UUCP mail for the class $=X. See SITECONFIG mc Macro (Obsolete) on page 609 for a discussion of UUCP relays in general, and how this macro relates to $V, $W, and $Y macros.

$y

Name of the controlling TTY All versions

The $y macro holds the name of the controlling terminal device, if there is one. The controlling terminal is determined by first calling ttyname(3) with the sendmail program’s standard error output as an argument. If ttyname(3) returns the name of a terminal device (such as /dev/ttypa), sendmail strips everything up to and including the last / character and stores the result into $y.

$y is intended for use in debugging sendmail problems. It is not used internally by sendmail. In determining whether it can write to a user’s terminal screen, sendmail calls ttyname(3) separately on its standard input, output, and error output without updating $y.

Note that the device name in $y depends on the implementation of ttyname(3). Under BSD Unix, all terminals are in /dev, whereas under other versions of Unix they can be in subdirectories such as /dev/ttys. Also note that $y is defined only if TTYNAME is defined (TTYNAME on page 148) when sendmail is compiled.

$y is transient. If it is defined in the configuration file or the command line, that definition will be ignored by sendmail. Finally, note that $y is set only when mail is being sent and, therefore, is of most value in headers.

$Y

The UUCP relay for unclassified hosts mc configuration

$Y holds as its value the name of the host that will handle all UUCP mail that was not otherwise handled by class $=V, $=W, or $=X. See SITECONFIG mc Macro (Obsolete) on page 609 for a discussion of UUCP relays in general, and how this macro relates to $V, $W, and $X macros.

$z

The recipient’s home directory All versions

The $z macro holds the location of the local user’s home directory. This macro is given a value only if the delivery agent has the F=w flag set (F=w on page 781)[329] and if delivery is to a user (rather than a file or a program). The home directory is looked up using the method defined by the MailboxDatabase option (MailboxDatabase on page 1042)[330] and that directory’s location is placed into this $z macro.

The sendmail program uses $z to access a user’s ~/.forward file and to save failed mail to a user’s ~/dead-letter file.

$z can be passed in the A= equate to a custom-written local delivery agent. One reason to do so would be to deliver mail to a user’s home directory rather than to a central spool directory. $z is also very useful with the ForwardPath option (ForwardPath on page 1034).

$z is transient. If it is defined in the configuration file or the command line, that definition will be ignored by sendmail. Note that a $& prefix is necessary when you reference this macro in rules (that is, use $&z, not $z).

$Z

Version of the mc configuration mc configuration

When you are configuring with the mc technique, the version of the configuration file can be augmented by defining confCF_VERSION in your mc file:

define(`confCF_VERSION', `ver')dnl

This statement causes the value ver to be appended to the default value in $Z. A forward slash character will separate the two. The default value in $Z varies depending on your sendmail version. If your version were V8.12.7, the aforementioned m4 definition would yield the following macro definition:

DZ8.12.7/ver

$Z is generally used as part of the SmtpGreetingMessage ($e) option’s declaration (SmtpGreetingMessage on page 1093):

O SmtpGreetingMessage=$j Sendmail $v/$Z; $b

Note that this version is different from the version declared with the VERSIONID mc configuration macro (VERSIONID m4 macro on page 593). Also note that this is the configuration file version, not the version of the sendmail program as stored in $v.

Prior to V8 sendmail, the configuration file version was stored in $V.



[301] * Prior to V8.7, the -oM option (M on page 1118) was used to define macros on the command line. Although that option still works, the -M command-line switch is now recommended as the preferred technique.

[302] * When you use this debugging switch, you will notice that operators such as $* are implemented as macros too.

[303] * For V8 sendmail, r and s should be set with the -p command-line switch (-p on page 246).

[304] * But you still might need to declare an occasional macro in your configuration file to solve unusual problems.

[305] * Beginning with V8.7, both single- and multicharacter names can be used.

[306] As an artifact of this scheme, a single character surrounded in curly braces is treated as though the curly braces were absent:

DXtexta single-character name

D{X}textthe same beginning with V8.7

[307] * Prior to V8.10, the maximum length was hardcoded at 20 characters.

[308] One for V8.7 and many for V8.8 and later.

[309] * Prior to V8.9, expansions with $& remained a single token even if they were legitimately multitokened. Beginning with V8.9, $& correctly returns multitokens when a value is multitokened.

[310] * This is also called xtext translation and is documented in RFC1891.

[311] * Although use of the -d35.9,21.12 debugging command-line argument can help.

[312] Note that these are the exception to the usual rule in that they are all uppercase letters. In a way this makes sense because they are being used by the configuration file, not by the internals of the sendmail program.

[313] * Bugs in Ultrix and OSF/1 (and maybe others) break the ident protocol.

[314] * The actual time depends on the local time zone.

[315] * BODY=BINARYMIME might be an option in the future.

[316] * Unless the -t command-line argument is used with makemap to change the separator.

[317] * Unless the -t command-line argument is used with makemap to change the separator.

[318] * The format produced by ctime(3) varies depending on your location.

[319] * Prior to V8, $j had to be defined in the configuration file.

[320] * TRUST_POPEN was a security risk and was eliminated from V8.10 sendmail. Instead of defining it, consider creating an /etc/whoami file and populating it or defining $k directly in your configuration file.

[321] * $m is the NIS domain for pre-V8 versions of Sun sendmail, and $m is the original user address for IDA sendmail.

[322] * Because the LHS of rules are case-insensitive, you cannot use just this macro to detect the difference between -bd and -bD.

[323] * Prior to V8.7, this behavior was tied to the local delivery agent.

[324] Prior to V8.7, looking up the user’s home directory was tied to the local delivery agent.

[325] Prior to V8.12, the getpwnam(3) routine was used.

[326] * Prior to V8, only $w was checked.

[327] * Prior to V8.7, this behavior was tied to the local delivery agent.

[328] Prior to V8.12, the getpwnam(3) routine was used.

[329] * Prior to V8.7, this behavior was tied to the local delivery agent.

[330] * Prior to V8.12, the getpwnam(3) routine was used.