25.4 ?flags? in Header Definitions
The name part
of the H configuration command can be prefixed
with a list of flags. This list, if present, must be
surrounded by ? characters:
H?flags?name:field
The ? characters must immediately follow the
H and immediately precede the
name with no intervening spaces. If a space
precedes the first ?, that ? is
misinterpreted as part of the header name,
rather than as the start of a list of flags, and this error message
is printed:
header syntax error, line " ?flags?name: field"
note leading space
If the first ? is present but the second is
absent, sendmail prints the same error message
and skips that H configuration command. The flags
that are listed between the ? characters
correspond to flags that are listed with delivery agent
F= equates. When processing a mail message for
forwarding or delivery, sendmail adds a header
line if a flag is common to both the H definition
list of flags and the delivery agent's list of
flags. For example:
H?P?Return-Path: <$g>
This H definition begins with a
P flag. This tells sendmail
to add this header line to the mail message only if a selected
delivery agent also contains that flag. Because the
Return-Path: header (Return-Path:)
should be added only during final delivery, the P
flag appears only in the prog and
local delivery agent definitions:
Mprog, P=/bin/sh, F=lsDFMeuP , S=10, R=20, A=sh -c $u
Mlocal, P=/bin/mail, F=rlsDFMmnP , S=10, R=20, A=mail -d $u
note
No check is made to ensure that the H flags
correspond to existing delivery agent flags. Beware that if a
corresponding F= flag does not exist in some
delivery agent definition, that header can never be added to any mail
message.
Care should be used to avoid selecting flags that have other meanings
for delivery agents. Table 20-19 in Section 20.8 lists all the delivery agent flags that have
predefined meanings, including those traditionally used with header
definitions.
25.4.1 Macros Force Header Inclusion
Beginning with V8.12 it is possible to add a header to a message by
placing a sendmail macro between the
? characters instead of, or in addition to, using
flags (Section 25.4). But note that for V8.10 and
V8.11 only, the ? character method was omitted,
and only a macro could appear in that position:
H?flags?X-Added-Header: value all versions
H${macro name}X-Added-Header: value V8.10 and V8.11 only
H?${macro name}?X-Added-Header: value V8.12 and above
H?${macro name}flags?X-Added-Header: value V8.12 and above
In the last three examples, if the macro has a value (is defined and
is nonnull), the header will be added to the email message. If the
macro lacks a value (was not defined or was defined to be an empty
string), the header is not added to the message. The first and last
examples cause the header to be added if a corresponding flag appears
in the F= equate of the selected delivery agent.
Note that if the header is already in the message, it will remain
there, regardless of whether the macro is defined, or whether a flag
is in the appropriate F= equate.
To illustrate, consider dealing with a message that contains an
illegally formed Message-Id: header:
LOCAL_CONFIG
Kstorage macro
HMessage-Id: $>ScreenMessageId
H?${MsgId}?X-Authentication-Warning: ${MsgId}
C{persistentMacros} {dsn_envid}
LOCAL_RULESETS
SScreenMessageId
R < $+ @ $+ > $@ OK
R $* $: $(storage {MsgId} $@ Illegal Message-Id: $1 $)
The LOCAL_CONFIG part of this mc file declares a
macro-type database map (macro) that is used to store a value into a
sendmail macro via a rule set.
The LOCAL_CONFIG part of this mc file continues
with two H configuration file commands. The first
says that each Message-Id: header in the message
must be screened by the ScreenMessageId rule set.
The use of the $> operator (Section 25.5) ensures that sendmail
will strip RFC2822 parenthetical comments from the
header's value. The second H line
uses the V8.12 (and above) form of a macro between the
? characters. This tells
sendmail to add this header if the
${MsgId} has or is given a value. We discuss the
{persistentMacros} declaration soon.
The LOCAL_RULESETS part of this mc file declares
a single rule set. The ScreenMessageId rule set
has two rules. The first rule checks the workspace which contains the
value of the Message-Id: header with RFC2822
parenthetical comments stripped. If that value is formed by a user
and host part separated by an @ character and
surrounded by angle brace characters, the
Message-Id: header is correctly formed. By
returning anything other than the $#error delivery
agent, the message is allowed.
The second rule in the ScreenMessageId rule set
matches everything (the $* in the LHS), so the RHS
is always called. The RHS calls the storage
database map, which stores a value into the
${MsgId} macro. The value stored is the phrase
Illegal Message-Id: followed by the value of the
offending Message-Id: header.
By defining the ${MsgId},
sendmail will add a new header to the message
because of the mc file line:
H?${MsgId}?X-Authentication-Warning: ${MsgId}
If a message were to arrive with a bad Message-Id:
header, such as the following:
Message-Id: <167445390329650300582-mailer.exe v1.2>
the preceding rules would cause the following new header to be added
to the message:
X-Authentication-Warning: Illegal Message-Id: <167445390329650300582-mailer.exe v1.2>
Note that sendmail macros in header definitions
do not need the $& prefix because macros used
in header declarations are not processed when the configuration file
is read. They are instead processed when the header declaration line
is processed.
As a precaution, only store values into macros that you define. By
storing values into sendmail's
internally defined macros, you can easily corrupt the
sendmail program's operation,
with unforeseen results.
25.4.2 Macro-Included Headers Don't Survive Queueing
The inclusion of a header based on a macro's value
is guaranteed to work only when mail is first sent or delivered, and
can fail if the message is queued. Consider, for example, the desire
to include a header that prints one of the
sendmail program's macro
values:
LOCAL_CONFIG
H?${dsn_envid}?X-ENVID: ${dsn_envid}
The intention here is to record the value of the DSN envelope
identifier value in an X- header, if such an
identifier was supplied during the SMTP transaction. If a message is
received with a MAIL FROM: line such as the following, the envelope
identifier and ${dsn_envid}
macro's value will be given the text following the
ENVID= expression:
MAIL FROM: <bob@some.domain> ENVID=1234abcd5678
When this message is received, the ${dsn_envid}
macro will contain a value (the string
1234abcd5678) which will cause the
X-ENVID: header to be given a value:
X-ENVID: 1234abcd5678
If this message cannot be delivered right away and is deferred to the
queue instead, the previous header will be stored in the queue like
this:
H?${dsn_envid}?X-ENVID: 1234abcd5678
Note that the original mc file's
?${dsn_envid}? test is included in the queue file.
When this message is later delivered, the
${dsn_envid} macro will not have a value. That
macro is given a value only when the message is first received with
SMTP. As a consequence, when the message is delivered from the queue,
the ${dsn_envid} macro will lack a value and thus
the X-ENVID: header will not be included in the
delivered message.
If you need to base header inclusion on such macros, you should add
the macro's name to the
$={persistentMacros} class ($={persistentMacros}) to ensure that the macro's
value survives the queue process. Using this solution, the previous
mc file declaration will instead look like this:
LOCAL_CONFIG
H?${dsn_envid}?X-ENVID: ${dsn_envid}
C{persistentMacros} {dsn_envid}
Macros saved in the $={persistentMacros} class
will have their values saved when the message is queued and restored
when the message is delivered from the queue.
Note, however, that the $={persistentMacros} class
can be dangerous. To be safe, avoid adding any of
sendmail's internally defined
macros to this class.
|