mailsurr(4) mailsurr(4)
NAME
mailsurr, mailsurr.proto - files used to control routing of
mail
DESCRIPTION
/usr/lib/mail/mailsurr.proto is a prototype file for
/etc/mail/mailsurr. It is similar to /etc/mail/mailsurr, with
the exception that some lines start with a boolean expression
in angle brackets followed by a tab. When createSurr is run,
it reads this file as a basis for creating mailsurr. For each
line in the file it does the following:
If the line has no boolean expression, copy it to
mailsurr.
If the boolean expression evaluates to TRUE (based on
the flags in /etc/mail/mailflgs), copy the line to
mailsurr.
The mailsurr file contains routing and transport surrogate
commands used by the mail command. Each entry in mailsurr has
three (or four) whitespace-separated, single quote delimited
fields:
'sender' 'recipient' 'command' ['batch']
or a line that begins with either of
Defaults:
Translate-Defaults:
Entries and fields may span multiple lines, but leading
whitespace on field continuation lines is ignored. Fields
must be less than 1024 characters long after expansion (see
below). Case is always ignored for making comparisons.
The sender and recipient fields are regular expressions. If
the sender and recipient fields match those of the message
currently being processed, the associated command is invoked.
The command field may have one of the following forms:
A[ccept]
D[eny] [message]
L[ocal]
T[ranslate] [B=...;S=...;F=...;T=...;L=...;] R=[|]string
Copyright 1994 Novell, Inc. Page 1
mailsurr(4) mailsurr(4)
< [B=...;S=...;C=...;F=...;H=mailR-function;] command
> [B=...;W=...;] command
E[rrors] [B=...;W=...;] command
R[ewrite] mailR-function
The mailsurr file must be world readable. If a batching
specification (B=...;) is given, then the batch field must
also be given; this fourth field is discussed in the
``Batching'' section.
Regular Expressions
The sender and recipient fields are composed of regular
expressions (REs). The regular expressions matched are those
from ed(1), with simple parentheses () playing the role of
\(\) and the addition of the +, ? and | operators from egrep
[see grep(1)]. Any single quotes embedded within the REs must
be escaped by prepending them with a backslash or the RE is
not interpreted properly.
The mail command prepends a circumflex (^) to the start and
appends a dollar sign ($) to the end of each RE so that it
matches the entire string. Therefore it would be an error to
use ^RE$ in the sender and recipient fields. To provide case
insensitivity, all REs are converted to lower case before
compilation, and all sender and recipient information is
converted to lower case before comparison. This conversion is
done only for the purposes of RE pattern matching; the
information contained within the message's header is not
modified.
The sub-expression pattern matching capabilities of regexp may
be used in the command field, that is, \\n, where 1 < n < 9.
Any occurrences of \\n in the replacement string are
themselves replaced by the corresponding parenthesized (. . .)
substring in the matched pattern. The sub-expression fields
from both the sender and recipient fields are accessible, with
the fields numbered 1 to 9 from left to right.
Accept and Deny Commands
Accept instructs rmail to continue its processing with the
mailsurr file, but to ignore any subsequent matching Deny.
That is, unconditionally accept this message for delivery
processing. Deny instructs rmail to stop processing the
mailsurr file and to send a negative delivery notification,
along with the optional message, to the originator of the
message. Whichever is encountered first takes precedence.
Copyright 1994 Novell, Inc. Page 2
mailsurr(4) mailsurr(4)
< Delivery command
The intent of a < command is that it is invoked as part of the
transport and delivery mechanism, with the ready-for-delivery
message available to the command at its standard input. As
such, there are three conditions possible when the command
exits:
Success The command successfully delivered the message.
What actually constitutes successful delivery may be
different within the context of different
surrogates. The rmail process assumes that no more
processing is required for the message for the
current recipient.
Continue The command performed some function (logging remote
message traffic, for example) but did not do what
would be considered message delivery. The rmail
process continues to scan the mailsurr file looking
for some other delivery mechanism.
Failure The command encountered some catastrophic failure.
The rmail process stops processing the message and
sends to the originator of the message a non-
delivery notification that includes any stdout and
stderr output generated by the command.
The semantics of the < command field in the mailsurr file
allow the specification of exit codes that constitute success,
continue, and failure for each surrogate command individually.
See the section below on ``Exit State Specifications'' for
details.
Surrogate commands are executed by rmail directly. If any
shell syntax is required (metacharacters, redirection, and so
on), then the surrogate command must be of the form:
sh -c "shell command line . . ."
Special care must be taken to properly escape any embedded
back-slashes and other characters special to the shell as
stated in the ``Translate'' section above.
If there are no matching < commands, or all matching <
commands exit with a continue indication, rmail attempts to
deliver the message itself by assuming that the recipient is
local and delivering the message to /var/mail/recipient.
Copyright 1994 Novell, Inc. Page 3
mailsurr(4) mailsurr(4)
If there is a header rewriting command specified as H=mailR-
function, the specified mailR function will be executed prior
to delivery of the message to the command. Such rewriting
will only take affect for that command and will not be
permanent (as occurs with the Rewrite command). For example,
in this delivery command
'.+' '(.+)!(.+)' '< H=tosmtp;B=*; smtpqer -N %R \1' '\2'
the mailR function named tosmtp will be called before passing
the result to the program smtpqer.
Translate Command
Translate allows optional on-the-fly translation of recipient
address information. The recipient replacement string is
specified as R=string.
For example, given a command line of the form
'.+' '([^!]+)@(.+)\.EUO\.ATT\.com' 'Translate R=attmail!\\2!\\1'
and a recipient address of rob@sysa.EUO.ATT.COM the resulting
recipient address would be attmail!sysa!rob.
Should the first character after the equal sign be a `|', the
remainder of the string is taken as a command line to be
directly executed by rmail. If any sh(1) syntax is required
(metacharacters, redirection, and so on), then the surrogate
command must be of the form:
sh -c "shell command line . . ."
Special care must be taken to escape properly any embedded
back-slashes and single or double quotes, since rmail uses
double quoting to group whitespace delimited fields that are
meant to be considered as a single argument to execl [See
exec(2)]. As stated above, any occurrences of \\n are
replaced by the appropriate substring before the command is
executed.
It is assumed that the executed command will write one or more
replacement strings on stdout. The exit code of the command
is examined to determine the outcome of the translation:
Success The command successfully translated the address. If
the invoked command does not return at least one
replacement string (no output or just a newline),
the original address is not modified. If the
Copyright 1994 Novell, Inc. Page 4
mailsurr(4) mailsurr(4)
original address itself is returned as one of the
translations, the translations are added to the list
of addresses and the original address is not
modified.
Failure The command encountered some catastrophic failure.
Any translations read from stdout will be used, but
the rmail process will send to the originator of the
message a non-delivery notification that includes
any stderr output generated by the command.
The semantics of the Translate command field in the mailsurr
file allow the specification of exit codes that constitute
success and failure for each surrogate command individually.
See the section below on ``Exit State Specifications'' for
details.
The output of the translation command consists of one or more
lines of output containing the new addresses, one or more per
line, separated by white space. If batching is enabled (see
the section on ``Batching'' below), the output of the
translation command consists of the new addresses, but each
line of output must begin with the address for which that line
of output is the translation.
This mechanism is useful for mailing list expansions. For
example, the command line
'.+' '(.+)' 'Translate R=|findpath \\1'
allows local routing decisions to be made.
If the recipient address string is modified, mailsurr is
rescanned from the beginning with the new address(es), and any
prior determination of Accept (see above) is discarded.
When a recipient has been translated, the new recipient may
again be passed through the translation command for further
translation. (Recursive mailing lists are thus possible.)
Some translation commands can guarantee that their output is
fully translated and cannot be further translated. For these
commands, the state specification T=1; should be given. (If
the resulting address should not be processed further within
the surrogate file, the state specification L=1; should be
given. Local delivery to /var/mail/recipient will then be
attempted.)
Copyright 1994 Novell, Inc. Page 5
mailsurr(4) mailsurr(4)
If a recipient address translates into a recipient address
previously seen, it will not be placed onto the recipient list
again unless the name was translated recursively back to
itself.
If the returned recipient address begins with an exclamation
point ``!'' and E=1; is given, then all leading exclamation
points will be stripped. Because the default surrogate file
treats leading exclamation points as special, careful
consideration should be given as to whether stripping should
be performed. If a recipient address is passed in to the
translate command with a leading exclamation point, the
exclamation point should not be stripped.
Rewrite Command
Rewrite allows manipulation of the contents of a message. A
function is specified which will be looked up in the
/etc/mail/rewrite, which is written in the mailR language.
The mailR functions can be used to modify any of the headers
of the mail message, or the body.
For example,
# rewrite the headers of some messages
'.+' 'sysa!.+' 'Rewrite rewrite_for_sysa'
This specifies that the mailR function rewrite_for_sysa is to
be invoked on any mail message going to the machine named
sysa.
Once such rewriting has been done, any subsequent delivery
commands for this set of messages will be delivered separately
from those messages which did not undergo the rewriting. For
example, consider mail going to sysa!foo and sysb!foo. Some
of the headers had gotten rewritten for mail to sysa, and
didn't for mail to sysb, but both need to be sent to the
smtpqer command. Since the message is now in effect two
separate messages, the smtpqer command will be invoked twice,
once for sysa and once for sysb.
There are also two specially-named functions which, if they
are present in /etc/mail/rewrite, will always be executed.
The main() function will be executed after the message is read
in, and the local() function will be executed before the
message is delivered locally.
Copyright 1994 Novell, Inc. Page 6
mailsurr(4) mailsurr(4)
Local Command
Local instructs rmail to stop processing this address within
the surrogate file and attempt local delivery to
/var/mail/recipient. It is equivalent to a Translate command
with the state specification L=1; and a null translation
string.
Exit State Specifications
The syntax of the exit state specification is:
[state_id=ec[,ec[,. . .]];][state_id=ec[,ec[,. . .]];[. . .]]]
Whitespace may precede the exit state specification, but must
follow. state_ids can be specified in any order.
exit_state_id can have the value S, C, or F, and are used on
Delivery < and Translation commands. The special state_id of
T may be used in Translation commands, and is described in
that section. The special state_id of W may be used in
Postprocessing, > and Errors, commands, and is described in
those sections. The special state_id of B may be used to
specify batched processing and is described in the section
``Batching''.
ec can be:
any integer 0 < n < 255 [Negative exit values are not
possible. See exit(2) and wait(2).]
a range of integers of the form lower_limit-upper_limit
where the limits are > 0 and < 255, and
*, which implies anything
For example, a command field of the form:
'< S=1-5,99;C=0,12;F=*; command %R'
indicates that exit values of 1 through 5, and 99, are to be
considered success, values of 0 (zero) and 12 indicate
continue, and that anything else implies failure.
It may be possible for ambiguous entries to exist if two exit
states have the same value, for example, S=12,23;C=*;F=23,52;
or S=*;C=9;F=*;. To account for this, rmail looks for
explicit exit values (that is, not ``*'') in order of success,
continue, failure. Not finding an explicit match, rmail then
Copyright 1994 Novell, Inc. Page 7
mailsurr(4) mailsurr(4)
scans for ``*'' in the same order.
It is possible to eliminate an exit state completely by
covering all possible values with a different default or
setting a state's value to an impossible number. (Since exit
values must be between 0 and 255 (inclusive), a value of 256
is a good one to use.) For example, if you had a surrogate
command that was to log all message traffic, a mailsurr entry
of
'(.+)' '(.+)' '<C=*; logger \\1 \\2'
could never indicate success or failure.
Defaults: and Translate-Defaults: Lines
If not explicitly supplied, default exit code settings are
S=0;C=*; for < commands and S=0;F=*; for Translate commands.
The default exit code settings for delivery and translation
commands may be redefined by creating a separate line in the
mailsurr file of one of these forms:
Defaults: [S=. . .;][C=. . .;][F=. . .;]
Translate-Defaults: [S=. . .;][F=. . .;]
Defaults: lines are honored and the indicated default values
redefined when the line is encountered during the normal
processing of the mailsurr file. Therefore, to redefine the
defaults globally, the Defaults: line should be the first line
in the file. It is possible to have multiple Defaults: lines
in the mailsurr file, where each subsequent line overrides the
previous one.
> Postdelivery command
The intent of a > command is that it is invoked after a
successful delivery to do any post-delivery processing that
may be required. Matching > commands are executed only if
some < command indicates a successful delivery (see the
previous section) or local delivery processing is successful.
The mailsurr file is rescanned and all matching > commands,
not just those following the successful < command, are
executed in order. The exit status of an > command is
ignored.
Some commands exit quickly, while others may take a while.
The rmail command normally waits for the > command to exit
before continuing its processing. If it is better not to wait
Copyright 1994 Novell, Inc. Page 8
mailsurr(4) mailsurr(4)
for a particular command, the state specification W=1; should
be given.
Errors command
The intent of a Errors command is that it is invoked after an
unsuccessful delivery to do any post-delivery processing that
may be required. Matching Errors commands are executed only
if some < or Translate command indicates a failed delivery, or
local delivery processing is unsuccessful. The mailsurr file
is rescanned and all matching Errors commands, not just those
following the failed < or Translate command, are executed in
order. The exit status of an Errors command is ignored. The
state specification W=1; may be used just as for the >
command.
Batching
Some commands may be combined together for multiple
recipients. For example, the delivery commands
uux - sysa!rmail (tony)
uux - sysa!rmail (rob)
may be combined together into the single delivery command
uux - sysa!rmail (tony) (rob)
Note that there are essentially two parts to each of the above
commands, the non-varying left-hand part, and the varying
right-hand part. Combining two delivery lines going to a
common system just requires the use of the non-varying left-
hand side paired with all the remaining right-hand sides.
Combining the commands together allows for the more efficient
delivery of mail.
Note also that there are two possible limitations to be
imposed on such commands: the maximum size of the command line
as limited by the UNIX system, and the maximum size of buffers
used within the command. The first limitation is an
administerable kernel parameter, usually 5120 bytes, for the
combination of the parameters and environment (the command-
line length limitation); the second limitation is a function
of the command being used and varies from command to command.
For example, the internal buffers of most versions of uux
limit the command line to 1024 bytes. (Note also that there
are limitations on both sides of the network; even if the
limit for uux were raised on the local side, the limit must
Copyright 1994 Novell, Inc. Page 9
mailsurr(4) mailsurr(4)
remain at 1024 to be portable.)
To specify that a surrogate command is to be batched, the
batching specification of B=number is given along with any
exit code specifications. The number is the maximum size of
the command line to be used. It may also be specified as *,
in which case the system command-line limitations are used.
(The system command-line limitations may be overridden by
using the mailcnfg variable ARG_MAX.)
If batching is specified, then in addition to the command
field, a fourth batch field must also be specified. The
command field specifies the non-varying left-hand part, and
the batch field specifies the varying right-hand part. For
example, a specification for uux might be:
'.+' '([^!@]+)!(.+)' '< B=1024; uux - \\1!rmail' '(\\2)'
All surrogate commands which permit a UNIX command to be
executed may be batched.
Surrogate Command Keyletter Replacement.
Certain special sequences are textually-substituted in
surrogate commands before they are invoked:
%c value of the Content-Type: header line if present.
%C ``text'' or ``binary'', depending on an actual scan
of the content. This is independent of the value
of any Content-Type header line encountered (useful
when calling ckbinarsys.)
%D the local domain name. This will be either DOMAIN
from mailcnfg, or the value returned by sysinfo(2).
If there is no domain name, then an empty string.
%H the size of the message header in bytes.
%L the local system name. This will be either CLUSTER
from mailcnfg or the value returned by uname.
%l value of the Content-Length: header line: the size
of the message body in bytes.
%n the recipient's name (address).
%O the recipient's original address before any
translation
%R the full return path to the originator (useful for
sending replies, delivery failure notifications,
and so on)
Copyright 1994 Novell, Inc. Page 10
mailsurr(4) mailsurr(4)
%S the value of the Subject: header line, if present.
%U the local system name, as returned by uname.
%X the value of SMARTERHOST in mailcnfg.
\\n as described above, the corresponding (. . .)
substring in the matched patterns. This implies
that the regexp limitation of 9 substrings is
applied to the sender and recipient REs
collectively.
%keyletters
Other lowercase keyletters as specified in
/etc/mail/mailcnfg. See mailcnfg(4).
%{DNODOT} the local domain name, as in %D, but without the
leading dot (.).
%{name} The value of the /etc/mail/mailcnfg variable, or an
empty string if the value does not exist.
%[name] the value of first line of the first header named
name.
The sequences %L, %U, %D, and %keyletters are permitted within
the sender and recipient fields as well as in the command
fields.
Mail Surrogate Examples
Some examples of mail surrogates include the distribution of
message-waiting notifications to LAN-based recipients and
lighting Message-Waiting Lamps, the ability to mail output to
printers, and the logging of all rmail requests between remote
systems (messages passing through the local system). The
following is a sample mailsurr file:
#
# Some common remote mail surrogates follow. To activate any
# or all of them, remove the `#' (comment indicators) from
# the beginning of the appropriate lines. Remember that they
# will be tried in the order they are encountered in the file,
# so put preferred surrogates first.
# Prevent all shell meta-characters
'.+' '.*[`;&|^<>()].*' 'Deny'
# Map all names of the form local-machine!user -> user
'.+' '%L!(.+)' 'Translate R=\\1'
# Map all names of the form uname!user -> user
# Must be turned on when using mail in a cluster environment.
#'.+' '%U!(.+)' 'Translate R=\\1'
Copyright 1994 Novell, Inc. Page 11
mailsurr(4) mailsurr(4)
# Map all names of the form user@host -> host!user
'.+' '([^!@]+)@(.+)' 'Translate R=\\2!\\1'
# Map all names of the form host.uucp!user -> host!user
'.+' '([^!@]+)\\.uucp!(.+)' 'Translate R=\\1!\\2'
# Map all names of the form host.local-domain!user -> host!user
# DOMAIN= within /etc/mail/mailcnfg will override sysinfo(2).
'.+' '([^!@]+)%D!(.+)' 'Translate R=\\1!\\2'
# Allow access to `attmail' from remote system `sysa'
'sysa!.*' 'attmail!.+' 'Accept'
# Deny access to `attmail' from all other remote systems
'.+!.+' 'attmail!.+' 'Deny No access to AT&T Mail'
# Send mail for `laser' to attached laser printer
# Make certain that failures are reported via return mail.
'.+' 'laser' '< S=0;F=*; lp -dlaser'
# Run all local names through the mail alias processor
#
'.+' '[^!@]+' 'Translate B=*; R=|mailalias' '%n'
# If you wish to support a user name space of user@local-domain in
# addition to user@host.local-domain, then add the following translation,
# where DOMAIN is the local domain, and HOST.DOMAIN is where to send the
# mail. Note that %D contains a leading dot, so it cannot be used in the
# first regular expression.
#'.+' '!DOMAIN!(.+)' 'Translate R=!HOST%D!\1'
# For remote mail via nusend
#'.+' '([^!]+)!(.+)' '< nusend -d \\1 -s -e -!"rmail \\2" -'
# For remote mail via usend
'.+' '([^!]+)!(.+)'
'< usend -s -d\\1 -uNoLogin -!"rmail \\2" - '
# For remote mail via uucp
'.+' '([^!@]+)!.+' '<S=256;C=0;
ckbinarsys -t %C -s \\1'
'.+' '([^!@]+)!(.+)' '< uux - \\1!rmail (\\2)'
# For remote mail via smtp
#'.+' '([^!@]+)!(.+)' '< smtpqer %R \\1 \\2'
Copyright 1994 Novell, Inc. Page 12
mailsurr(4) mailsurr(4)
# If none of the above work, then let a router change the address.
#'.+' '.*[!@].*' 'Translate R=|smail -A %n'
# If none of the above work, then ship remote mail off to a smarter host.
# Make certain that SMARTERHOST= is defined within /etc/mail/mailcnfg.
#'.+' '.*[!@].*' 'Translate R=%X!%n'
# If you have a flat name space across multiple machines, but user-names only
# exist on disjoint machines, this entry will forward any name not known
# locally off to the given host.
#'.+' '[^!@]+' 'Translate T=1; R=|localmail -p -S @HOST.DOMAIN' '%n'
# Log successful message deliveries
'(.+)' '(.+)' '> logger \\1 \\2'
Note that invoking mail to read mail does not involve the
mailsurr file or any surrogate processing.
Security
Surrogate commands execute with the permissions of rmail (user
ID of the invoker, group ID of mail). This allows surrogate
commands to validate themselves, checking that their effective
group ID was mail at invocation time. This requires that all
additions to mailsurr be scrutinized before insertion to
prevent any unauthorized access to users' mail files. (Note
that some versions of the shell turn off the effective group
ID. If the surrogate command is a shell script and it
requires group mail permissions, the shell may be explicitly
invoked in the surrogate command with the -p option: sh -p
shell.script.) All surrogate commands are executed with the
path /usr/lib/mail/surrcmd:/usr/bin, and an environment
consisting of the SHELL=/usr/bin/sh, HOME, TZ and LOGNAME
variables. Other environment variables may be passed by
listing them in the mailcnfg variable SURR_EXPORT as a comma-
separated list (e.g. SURR_EXPORT=TERM,LINES,COLUMNS).
Debugging New mailsurr Entries
To debug mailsurr files, use the -T option of the mail
command. The -T option requires an argument that is taken as
the pathname of a test mailsurr file. If null (as in -T ""),
the system mailsurr file is used. Enter
mail -T test_file recipient
Copyright 1994 Novell, Inc. Page 13
mailsurr(4) mailsurr(4)
The result of using the -T option is displayed on standard
output and shows the inputs and resulting transformations as
mailsurr is processed by the mail command for the indicated
recipient.
Mail messages will never be sent or delivered when using the
-T option.
The -d and -# option may also be used to debug the system
surrogate files.
FILES
/etc/mail/mailsurr
/usr/lib/mail/surrcmd/* surrogate commands
/etc/mail/mailcnfg initialization information for mail
REFERENCES
ckbinarsys(1M), createSurr(1M), ed(1), exec(2), exit(2),
grep(1), mail(1), mailalias(1), mailcnfg(4), popen(3S),
regexp(5), sh(1), smtpqer(1M), sysinfo(2), uname(1), uux(1C),
wait(2)
NOTICES
Make the necessary changes in the mailsurr.proto file, then
run createSurr to update the mailsurr file.
It would be unwise to install new entries into the system
mailsurr file without verifying at least their syntactical
correctness via `mail -T . . . ' as described above.
Copyright 1994 Novell, Inc. Page 14