The sendmail program offers the -d command-line switch, which
allows you to observe sendmail’s inner workings
in detail. Understanding this switch can help you solve complex
email problems.
In earlier editions of this book, we attempted to document all the debugging switches available, and provided a table showing which were useful. For this edition, however, we will limit our detailed description to V8.14 sendmail and only to those debugging switches considered useful. This was done because debugging switches show the inner workings of sendmail, and, thus, those that are other than “useful” can change dramatically from release to release and are impossible to accurately represent in a static book.
The form for the -d
command-line switch is:
-dcategory.level,category.level,.... -dANSI ← V8.8 and above -dexpression.level,expression.level,.... ← V8.12 and above
The -d can appear alone, or
it can be followed by one or more
category.level pairs
separated by commas or, beginning with V8.8, by the word
ANSI. We cover the category.level
pairs first, then ANSI, and finally the
expression form.
The category limits debugging to an
aspect of sendmail (such as queuing or
aliasing). The level limits the
verbosity of sendmail (with low levels
producing the least output).
The category is either a positive
integer or a range of integer values specified as:
first-lastWhen category is a range,
first is a positive
integer that specifies the first category in the range. It
is followed by a hyphen character (-) and then
last, a positive integer
that specifies the last category in the range. The value of
first must be less than
the value of last, or the range
will be ignored.
The level is a positive integer. A level of 0 causes sendmail to produce no output for the category.
When the -d is specified
with neither category nor
level, an internal
sendmail default is
used:
0-99.1
This default causes sendmail to set all the categories, from zero through 99 inclusive, to a level of 1.
When category is included but
level is omitted, the value for
level defaults to 1. When
a dot (.) and level are included,
but category is omitted, the
value for category defaults to
0.
The maximum value that can be specified for a single
category is 99. The
maximum value for level is that
of an unsigned char (255 decimal). Any
value specified above the maximum is reduced to the maximum.
Nondigits for the category or
range evaluate to zero. Nondigits for the
level evaluate to
1.
The level specifies the maximum
amount of verbose output to produce. All levels below the
level specified also
produce output.
The expression that produces the maximum debugging output is:
-d0-99.127
But beware that debugging levels of 100 or greater can cause
sendmail to modify its
behavior. (For example, one category at such a high level
prevents sendmail from removing its
temporary files.) For this reason, -d0-99.99 is the maximum level
recommended.
Debugging can be turned on from the command line and from
within -bt rule-testing
mode (Add Debugging for Detail on page
318).
Beginning with V8.8 sendmail, a special debugging word can be specified at the command line to cause debugging output to become clearer:
-dANSI ← V8.8 and aboveANSI is case-sensitive and must be the only argument following
the -d. If you wish to
combine it with other debugging switches, you must specify
them separately:
-dANSI -d0.4
ANSI causes defined macros, class macros, and operators to be displayed in reverse video, as shown in Figure 15-1.
This is truly a “hack.” The escape code to highlight characters is hardcoded into sendmail. Your display must support ANSI-standard escape sequences for this to work. There is no plan to use standard termcap(5) library support for this “aid to rule-set hackers.”
Beginning with V8.12, sendmail has begun transitioning to more easily remembered alphanumeric debugging categories. For the V8 series, this is being accomplished by adding alphanumeric categories rather than replacing the existing numeric categories entirely.
The forms for this new way of specifying a debug category look like this:
-dprogram_check_process.level -dprogram_trace_process.level
Here, the -d is literal.
The program_ specifies the program for
which the debugging flag applies. Currently, the only
program_ available is “sm_” for
sendmail.
The check lets you know
that a particular category is intended for checks on limits,
states, or the rationality of values. The trace lets you know that a
particular category is intended to trace the behavior of a
section of code, or of behavior common to many sections of
code.
The _process specifies just what aspect of the code will be checked or traced. Table 15-1, we list the handful of new categories that currently use this new form.
All of these new categories are intended to be used by sendmail developers and are not generally useful to mail administrators. If you suspect you might need to use one of these categories, examine the sendmail code first to determine the effect of each, and then apply them in one window while examining the source in another.
When sendmail is given the -d debugging switch, it
internally performs three distinct actions. First, if the
category.level is
omitted, sendmail presets all
categories, 0–99 inclusively, to a level of 1. It then sets
the categories in the command line (if any) to the
corresponding levels specified (or to 1 if no level is
specified). Finally, it calls setbuf(3)
to place the standard output in unbuffered mode.
Setting categories 0–99 to a level of 1 has two side effects:
Usually, certain errors are not reported because they are tolerable, but a level of 1 generally causes those otherwise missing error messages to be printed. For example, if the aliases file is missing, sendmail does not perform aliasing but is silent about it. A category 27 level of 1, on the other hand, causes sendmail to print the reason it could not open the aliases file.
Because sendmail is usually silent about what it is doing, any debugging at all causes it to print a great deal of information about what it is trying to do and what it has done.
Note, however, that debugging should generally not be used in
combination with any -bd,
-bD, or -bs command-line switch.
Debugging output can interfere with normal SMTP
transactions, and thus can corrupt the transmission or
receipt of SMTP email. Use these debugging switches only
when you are absolutely certain that no actual mail will be
impacted (as might be the case on a machine that normally
does not receive mail).
Some debugging output references C-language structures that are internal to sendmail. For those, it will help if you have access to sendmail source. One subroutine, called printaddr( ), is used to dump complete details about all the recipients for a given mail message. This subroutine is used by many categories of debugging output, but rather than describe it repeatedly, we describe it once, here, and reference this description as needed.
The sendmail program’s internal printaddr( ) subroutine prints details about addresses. The sendmail program views an address as more than just an expression such as gw@wash.dc.gov. Internally, it represents every address with a C-language structure. The printaddr( ) routine prints the values stored in most of the items of that structure. Its output looks like this:
subroutine: ra= addr: mailermnum(mname), host `hname' user `uname', ruser `rname' state=state, next=link, aliasaname, uid user-id, gid group-id flags=fhex<names here> owner=owner, home="home", fullname="fname" orcpt="oparam", statmta=mta, status=statusfinalrcpt="finalrcpt" rstatus="rstatus" statdate=statdate
First, sendmail prints the address in
memory, ra, of the C-language
struct that contains the
information necessary to deliver a mail message. It then
prints the information in that structure:
The mail address as text--e.g., you@uofa.edu.
Number of the delivery agent to be used (an index into the array of delivery agents).
Symbolic name of that delivery agent (from
rule set parse 0, $#).
Name of the recipient’s host machine (from
rule set parse 0, $@).
Recipient’s mail name (from rule set parse
0, $:).
Recipient’s login name, if known; otherwise,
it is <null>.
The current state of the message in text form. See Table 15-2 for a list of the text names that can be printed, and their meanings.
|
State name |
Description |
|
OK |
The message is initially in an untried, OK state. |
|
DONTSEND |
The message must not be sent to this address. |
|
BADADDR |
The address is bad. |
|
QUEUEUP |
The message should be queued for this address. |
|
RETRY |
Proceed to the next MX server and try again. |
|
SENT |
The message was successfully delivered or relayed to this address. |
|
VERIFIED |
The address has been verified, but not alias-expanded. |
|
EXPANDED |
The address has been alias-expanded. |
|
SENDER |
This address is that of the sender. |
|
CLONED |
This address was cloned as part of envelope splitting. |
|
DISCARDED |
This recipient address must be discarded. |
|
REPLACED |
This address was replaced by the User Database or the localaddr rule set 5. |
|
REMOVED |
This address has been removed from the recipient list. |
|
DUPLICATE |
This is a duplicate address that has been suppressed. |
|
INCLUDED |
This address resulted in an |
Address in memory of the next C-language structure of information about the next recipient in the list of recipients.
Address in memory of the next C-language structure of information about the alias that led to this address (if there was one).
The user-id and
group-id assigned to this
delivery agent. These values are derived from the
ownership permissions of an :include: file or a
~/.forward file (Delivery to Files on page 466) or the
user-id and
group-id of a local user or
the DefaultUser’s identity (DefaultUser on page 1000).
A hexadecimal representation of the possible envelope flags. This is immediately followed by a list of the names of flags inside the angle brackets. We don’t describe those names here.
The owner- that corresponds to the
aname, if there is
one.
Home directory of the recipient (for local mail only).
Full name of the recipient, if it is known.
The ORCPT parameter to the SMTP RCPT command, if there was one.
The name of the MTA host (such as “other.dc.gov”) that generated the Delivery Status Notification (DSN) message shown in rstatus.
The DSN FinalRecipient: value—for example,
“RFC822; gw@wash.dc.gov.”
The DSN number as text.
The DSN message from the remote receiving host’s MTA.
The date and time the status of this address changed.
The -D command-line switch
is used to redirect sendmail’s debugging output into a file
for later examination. It is used like this, where
file is the name of an
existing or new file:
-D fileThe -D command-line switch
(if used) must precede the -d switch on the same command line;
otherwise, the following error will print and all debugging
output will be printed to the standard output (possibly
causing you to miss seeing the error):
-D file must be before -d
The file specified with -D must live in a
directory that is writable by the user running sendmail. If the file
does not exist, it will be created. If the file already
exists, it will be silently appended to.
Extra care must be exercised when using the -D command-line switch as
root because the target file
will be appended to, even if it is a symbolic link to an
important file. For example, when /tmp/foo is a
non-root-owned symbolic link
that points to /etc/passwd, the following command line,
when run by root, will silently append debugging information
to the /etc/passwd
file:
# /usr/sbin/sendmail -D /tmp/foo -d0.1 -bt < /dev/nullBecause debugging is so closely tied to the internals of sendmail, we no longer cover all debugging switches in detail. In the reference section at the end of this chapter, we cover in detail only those debugging switches that are useful to the administrator. In Table 15-3, we list all the debugging switches by category, regardless of their usefulness, and give a brief description of each. If you need more detail about those we do not document, we suggest you use sendmail/TRACEFLAGS as a guide to the appropriate source code files.
|
Category |
Description |
|
|
Display system configuration information. |
|
|
Show sender information. |
|
|
Trace sendmail’s exit information. |
|
|
Print the load average. |
|
|
Trace disk-space calculations. |
|
|
Trace timed events. |
|
|
Show failed mail. |
|
|
Trace the queue filename. |
|
|
Trace hostname canonicalization. |
|
|
Trace identd exchanges. |
|
|
Trace recipient delivery. |
|
|
Trace delivery generally. |
|
|
Trace mapping of relative host. |
|
|
Trace the envelope and envelope splitting. |
|
|
Show header field commas. |
|
|
Trace incoming connections. |
|
|
Trace outgoing connections. |
|
|
Trace MX record lookups. |
|
|
Trace SMTP replies. |
|
|
Show ESMTP MAIL and RCPT parameters. |
|
|
Show delivery agent selection. |
|
|
Trace rules and rule sets. |
|
|
Show address tokenization. |
|
|
Unused. |
|
|
Trace assembly of address tokens. |
|
|
Trace the send-to list. |
|
|
Trace recipient queueing. |
|
|
Trace aliasing, ~/.forward file handling, and controlling user. |
|
|
Trace the User Database. |
|
|
Trace |
|
|
Trace header processing. |
|
|
Trace header validation. |
|
|
Show collected headers. |
|
|
Watch crackaddr( ). |
|
|
Trace header generation and skipping. |
|
|
Trace macro definition and expansion. |
|
|
Trace the internal symbol table. |
|
|
Trace setting of options and classes. |
|
|
Trace database processing. |
|
|
Display digit database mapping. |
|
|
Trace processing of the queue. |
|
|
Trace queue ordering. |
|
|
Trace connection caching. |
|
|
Trace MIME conversions. |
|
|
Trace safefile( ). |
|
|
Trace envelope sender. |
|
|
Show xf file’s descriptors. |
|
|
Trace effective/real user/group IDs. |
|
|
Trace calls to the |
|
|
Trace checkcompat( ). |
|
|
Trace envelope dropping. |
|
|
Trace unlocking and prevent unlink of
|
|
|
Trace controlling TTY. |
|
|
Trace xclose( ). |
|
|
Show error return and output message. |
|
|
Trace file locking. |
|
|
Trace persistent host status. |
|
|
Monitor vsnprintf( ) overflows. |
|
|
Trace buffered filesystem I/O. |
|
|
Trace XLA from contrib. |
|
|
Trace database map lookups inside rewrite( ). |
|
|
Trace gethostbyname( ). |
|
|
Log file descriptors before and after all deliveries. |
|
|
Trace queue processing forks. |
|
|
Trace Milter interactions. |
|
|
Trace nonallowed user actions. |
|
|
Unused. |
|
|
Unused. |
|
|
Unused. |
|
|
Queue scheduling. |
|
|
Queue quarantining. |
|
|
Milter quarantine on errors. |
|
|
Unused. |
|
|
Queue shared memory updates. |
|
|
Unused. |
|
|
Unused. |
|
|
Unused. |
|
|
Unused. |
|
|
Unused. |
|
|
Unused. |
|
|
Trace |
|
|
Trace > option for remote mode (Sun version). |
|
|
Unused. |
|
|
Collection timeout. |
|
|
Delivery timeout. |
|
|
The internal dprintf database map. |
|
|
Unused. |
|
|
Unused. |
|
|
Unused. |
|
|
Unused. |
|
|
Unused. |
|
|
Log caching and uncaching connections. |
|
|
Unused. |
|
|
Unused. |
|
|
Force RSET failure. |
|
|
Trace AUTH= authentication. |
|
|
Allow SSL_CTX_set_info_callback( ) call. |
|
|
Trace setting of auto mode for I/O. |
|
|
Trace timers (commented out in the code). |
|
|
Prevent backgrounding the daemon. |
It is best to debug sendmail in a window environment, within script(1), with emacs(1), or something similar. Debugging output can run to many screens.
Sometimes debugging output seems not to be printed:
% /usr/sbin/sendmail -d11.1 you < /dev/null
%When this happens, add the -v command-line switch
to keep the output attached to your screen:
% /usr/sbin/sendmail -v -d11.1 you < /dev/null
← many lines of output here
%There must be no space between the -d and its numeric
arguments. If you put space there, the numeric
arguments might be interpreted as recipient
addresses.
There is no way to isolate a single category and level. Each level includes the output of all lower levels within a specified category.
The concept of debugging, versus other uses of
-d, is muddled
in sendmail. Tracing, for
example, can be valuable for tuning a
configuration file, yet such an activity is not
really debugging. We hope to make the distinction
clear by documenting only the “useful” debugging
switches, and omitting the true code-level
debugging switches from this chapter.
Because the -d command-line switch shows details of
the internals of sendmail,
the developers of sendmail
consider that output to be unpublished material.
As a consequence, the details of debugging output
documented here might differ from what you see
when running versions above or below V8.14. You
are strongly encouraged to avoid writing a program
to parse debugging output because such a program
might become obsolete with a future release of
sendmail.
Beginning with V8.13
sendmail, the -d switch may no longer
be combined with the -q switch. This prevents direct tracing
of the queueing process:
WARNING: Cannot use -d with -q. Disabling debugging.
The sendmail debugging switches vary from vendor to vendor and from version to version. This section is specific to V8.14 sendmail. These switches are perhaps best used with a copy of the sendmail source by your side. Be further advised that many of the internal details shown here will change as sendmail continues to evolve and improve.
In Table 15-4, we provide a detailed description of categories that we consider useful for the system administrator who is trying to solve an email problem. Categories that are of interest only to sendmail developers are omitted. If you need to use a category not listed here, you must examine the source and find a category that will solve your unusual problem.
|
Category |
§ |
Description |
|
|
-d0.1 on page 542 |
Print version, compilation, and interface information. |
|
|
-d0.4 on page 542 |
Our name and aliases |
|
|
-d0.10 on page 543 |
Operating system defines |
|
|
-d0.12 on page 544 |
Print library (libsm) defines. |
|
|
-d0.13 on page 544 |
Print _FFR defines. |
|
|
-d0.15 on page 544 |
Dump delivery agents. |
|
|
-d0.20 on page 544 |
Print network address of each interface. |
|
|
-d2.1 on page 544 |
End with finis( ). |
|
|
-d2.9 on page 546 |
Show file descriptors with dumpfd( ). |
|
|
-d4.80 on page 547 |
Trace enoughspace( ). |
|
|
-d6.1 on page 547 |
Show failed mail. |
|
|
-d8.1 on page 548 |
DNS name resolution. |
|
|
-d8.2 on page 548 |
Call to getcanonname(3). |
|
|
-d8.3 on page 549 |
Trace dropped local hostnames. |
|
|
-d8.5 on page 549 |
Hostname being tried in getcanonname(3). |
|
|
-d8.7 on page 549 |
Yes/no response to |
|
|
-d8.8 on page 549 |
Resolver debugging. |
|
|
-d11.1 on page 550 |
Trace delivery. |
|
|
-d11.2 on page 552 |
Show the user-id running as during delivery. |
|
|
-d12.1 on page 552 |
Show mapping of relative host. |
|
|
-d13.1 on page 553 |
Show delivery. |
|
|
-d20.1 on page 553 |
Show resolving delivery agent: parseaddr( ). |
|
|
-d21.1 on page 554 |
Trace rewriting rules. |
|
|
-d21.2 on page 554 |
Trace |
|
|
-d22.1 on page 554 |
Trace tokenizing an address: prescan( ). |
|
|
-d22.11 on page 555 |
Show address before prescan. |
|
|
-d22.12 on page 555 |
Show address after prescan. |
|
|
-d25.1 on page 555 |
Trace “sendtolist”. |
|
|
-d26.1 on page 555 |
Trace recipient queueing. |
|
|
-d27.1 on page 556 |
Trace aliasing. |
|
|
-d27.2 on page 557 |
Include file, self-reference, error on home. |
|
|
-d27.3 on page 558 |
Forwarding path and alias wait. |
|
|
-d27.4 on page 558 |
Print not safe. |
|
|
-d27.5 on page 559 |
Trace aliasing with printaddr( ). |
|
|
-d27.8 on page 559 |
Show setting up an alias map. |
|
|
-d27.9 on page 559 |
Show
user-id/group-id
changes with |
|
|
-d28.1 on page 560 |
Trace user database transactions. |
|
|
-d29.1 on page 560 |
Special rewrite of local recipient. |
|
|
-d29.4 on page 561 |
Trace fuzzy matching. |
|
|
-d31.2 on page 561 |
Trace processing of headers. |
|
|
-d34.1 on page 562 |
Watch header assembly for output. |
|
|
-d34.11 on page 562 |
Trace header generation and skipping. |
|
|
-d35.9 on page 563 |
Macro values defined. |
|
|
-d37.1 on page 563 |
Trace setting of options. |
|
|
-d37.8 on page 564 |
Trace adding of words to a class. |
|
|
-d38.2 on page 564 |
Show database map opens and failures. |
|
|
-d38.3 on page 565 |
Show passes. |
|
|
-d38.4 on page 565 |
Show result of database map open. |
|
|
-d38.9 on page 566 |
Trace database map closings and appends. |
|
|
-d38.10 on page 567 |
Trace NIS search for |
|
|
-d38.12 on page 568 |
Trace database map stores. |
|
|
-d38.19 on page 568 |
Trace switched map finds. |
|
|
-d38.20 on page 568 |
Trace database map lookups. |
|
|
-d44.4 on page 569 |
Trace safefile( ). |
|
|
-d44.5 on page 571 |
Trace writable( ). |
|
|
-d48.2 on page 572 |
Trace calls to the |
|
|
-d49.1 on page 572 |
Trace checkcompat( ). |
|
|
-d52.1 on page 572 |
Show disconnect from controlling TTY. |
|
|
-d52.100 on page 573 |
Prevent disconnect from controlling TTY. |
|
|
-d60.1 on page 573 |
Trace database map lookups inside rewrite( ). |
|
|
-d99.100 on page 574 |
Prevent backgrounding the daemon. |
Print version, compilation, and interface information Debug command-line switch
The -d0.1 (a.k.a.
-d0) debugging
switch previously prevented
sendmail from forking and
detaching itself, but that function has been moved
to the -d99.100
debugging switch. The -d0.1 debugging switch now just tells
sendmail to print information
about its version:
Version 8.14.1
Compiled with: LOG MATCHGECOS NAMED_BIND NDBM NEWDB NETINET NETUNIX
NIS
= == == == == == = SYSTEM IDENTITY (after readcf) = == == == == == =
(short domain name) $w = here
(canonical domain name) $j = here.US.EDU
(subdomain name) $m = US.EDU
(node name) $k = here
= == == == == == == == == == == == == == == == == == == == == ==
== == == == == == =The Version is the
current version of sendmail.
Note that for Sun, the number can look like SMI-8.7.5 or 8.14.1+Sun.
The Compiled with:
lists the compile-time definitions that were
specified when sendmail was
compiled. All the available definitions are listed
in Table 3-2
on page 105.
The SYSTEM IDENTITY
shows the value assigned to four important macros.
The meaning of each macro is shown in Table 21-7 on page 798.
Our name and aliases Debug command-line switch
The -d0.4 debugging
switch tells sendmail to print
several lines of information in addition to those
printed by -d0.1:
Version 8.14.1
Compiled with: LOG MATCHGECOS NAMED_BIND NDBM NEWDB NETINET NETUNIX
NIS
canonical name: here.US.EDU ← additional
UUCP nodename: here ← additional
a.k.a.: [123.45.67.89] ← additional
= == == == == == = SYSTEM IDENTITY (after readcf) = == == == == == =
(short domain name) $w = here
(canonical domain name) $j = here.US.EDU
(subdomain name) $m = US.EDU
(node name) $k = here
= == == == == == == == == == == == == == == == == == == == == ==
== == == == == == =To find the canonical name of the local host,
sendmail calls
gethostname( ). If that call
fails, the name localhost is
used. The hostname is then looked up with the
internal routine
sm_gethostbyname( ), which
gathers additional information (such as other names
and addresses for the machine) and fixes several
bugs in some operating system versions of the
gethostby... routines. Next
the canonical name for the local host is looked up.
For operating systems that normally support switched
services, the name is looked up as specified. For
systems that specify switched services in the
configuration file’s ServiceSwitchFile option (ServiceSwitchFile on page 1088),
switched services are not used because the
configuration file has not been read yet. (This
canonicalization process can be traced with the
-d61.10
debugging switch.) If the canonical name is found
and that name contains a dot,
sendmail saves the part of
the name to the right of the leftmost dot as the
domain name in the $m
sendmail macro ($m on page 833). It also appends
the part of the name to the left of the leftmost dot
to the class w
($=w on page 876).
If the canonical name doesn’t contain a dot, the
$m macro is
undefined, and the whole name is appended to the
class $=w.
In addition, sendmail also sets
the $k
sendmail macro ($k on page 831) to be the
correct UUCP name for the machine. It uses
uname(3), if available, to
find that name. Otherwise, it uses the same strategy
as for class $=w.
Then sendmail lists any other
name, or address (in square brackets), that it
found. If it finds any, it prints the found item
prefixed by an a.k.a.: and adds each found item to the
class $=w. The
aliases listed are only those found using
gethostbyname(3). To see each
entry as it is added to the class $=w, use the -d37.8 debugging
switch.
Finally, sendmail scans the
network hardware to find any other names associated
with interfaces. If the
ioctl(2) call to get that
information fails, the -d0.4 debugging switch causes
sendmail to print that
failure:
SIOGIFCONF failed: ← reason hereIf any are found, each is printed with an a.k.a.: prefix and added
to the class $=w.
Operating system defines Debug command-line switch
The -d0.10
debugging switch causes
sendmail to print all the
operating system-specific definitions that were used
to compile your specific version of
sendmail. This output prints
after the “Compiled with:” information described
earlier:
OS Defines: HASFCHOWN HASFCHMOD HASFLOCK HASGETUSERSHELL
HASINITGROUPS HASLSTAT HASNICE HASRANDOM HASRRESVPORT
HASSETREUID HASSETSID HASSETVBUF HASUNAME HASWAITPID IDENTPROTO
IP_SRCROUTE SAFENFSPATHCONF USE_DOUBLE_FORK
Conf file: /etc/mail/submit.cf (default for MSP)
Conf file: /etc/mail/sendmail.cf (default for MTA)
Pid file: /var/run/sendmail.pid (default)The OS Defines are
described in Table 3-2
on page 105. Most are automatically determined
during compilation; others are specified in
Makefile.
A Kernel symbols:
line can also print on your machine. If so, it will
show the name of the file (such as
/dev/ksyms) that is accessed
to determine the load average. It is automatically
defined correctly when conf.c
is compiled.
The location of the configuration files and the process identifier file is defined in the Makefile and conf.h in the sendmail source (_PATH... on page 131).
Print library (libsm) defines Debug command-line switch
The -d0.12
debugging switch, in addition to the information
displayed by the -d0.10 debugging switch, causes the
list of the sendmail library
(libsm) macros that were
defined at compile time to be displayed:
libsm Defines: SM_CONF_BROKEN_STRTOD SM_CONF_GETOPT SM_CONF_SETITIMER
SM_CONF_SHM SM_CONF_STDDEF_H SM_CONF_UID_GID SM_HEAP_CHECKPrint _FFR defines Debug command-line switch
The -d0.13
debugging switch, in addition to the information
displayed by the -d0.12 debugging switch, causes the
list of _FFR additions that were defined at compile
time to be displayed:
FFR Defines: _FFR_NO_PIPE
Unless you define such additions yourself, chances are slim that any will be printed with this debugging switch.
Dump delivery agents Debug command-line switch
The -d0.15
debugging switch causes
sendmail to display how it
interpreted its delivery agent definitions. The
clarity and completeness of the delivery agent
information vary with the version of
sendmail. See the =M rule-testing command
(Show Delivery Agents with =M on
page 307) for an example of this output.
Print network address of each interface Debug command-line switch
When sendmail scans the network
hardware to find other names for the local host, it
uses only those names that are new. Each new name
was printed by the -d0.4 debugging switch described
earlier. To see every name that
sendmail finds, new and old
alike, use the -d0.20 debugging switch:
128.32.201.55← already found127.0.0.1← found new a.k.a.: [127.0.0.1]
End with finis( ) Debug command-line switch
Ordinarily, sendmail exits
silently when it is done (unless an error causes an
error message to be printed). The -d2.1 (a.k.a. -d2) debugging switch
causes sendmail to print three
useful values when it exits. The message it prints
looks like this:
= == =finis: stat number e_id=qid e_flags=flags
The number is the final value of
the sendmail program’s global
ExitStat
variable. It is usually updated to contain the
latest error value as defined in
<sysexits.h >. See
sendmail’s exit( ) Status
on page 228 for a detailed description of the
possible exit values.
The qid is either the queue
identifier (such as g7PI04TK027759), or NOQUEUE if the message
was never assigned an identifier (if it was never
queued, for instance).
The flags is a hexadecimal
representation of the possible envelope flags
followed by a text representation of those flags in
angle brackets with the leading EF_ removed. For
example:
201003<OLDSTYLE,INQUEUE,GLOBALERRS,HAS_DF>
These are the envelope flags that were in effect with the current envelope when sendmail exited. The possible values are shown in Table 15-5.
|
Text |
Hex |
Description |
|
EF_OLDSTYLE |
|
Use spaces (not commas) in headers. |
|
EF_INQUEUE |
|
This message is fully queued. |
|
EF_NO_BODY_RETN |
|
Omit message body on error. |
|
EF_CLRQUEUE |
|
Disk copy is no longer needed. |
|
EF_SENDRECEIPT |
|
Send a return receipt. |
|
EF_FATALERRS |
|
Fatal errors occurred. |
|
EF_DELETE_BCC |
|
Delete |
|
EF_RESPONSE |
|
This is an error or return receipt. |
|
EF_RESENT |
|
This message is being forwarded. |
|
EF_VRFYONLY |
|
Verify only (don’t expand aliases). |
|
EF_WARNING |
|
Warning message has been sent. |
|
EF_QUEUERUN |
|
This envelope is from the queue. |
|
EF_GLOBALERRS |
|
Treat errors as global. |
|
EF_PM_NOTIFY |
|
Send return mail to postmaster. |
|
EF_METOO |
|
Send to me too. |
|
EF_LOGSENDER |
|
Need to log the sender. |
|
EF_NORECEIPT |
|
Suppress all return receipts. |
|
EF_HAS8BIT |
|
Has at least one 8-bit character in body. |
|
EF_NL_NOT_EOL |
|
Don’t accept raw newline as end-of-line. |
|
EF_CRLF_NOT_EOL |
|
Don’t accept carriage-return/line-feed as end-of-line. |
|
EF_RET_PARAM |
|
SMTP RCPT command had RET argument. |
|
EF_HAS_DF |
|
Set when the |
|
EF_IS_MIME |
|
This is really a MIME message. |
|
EF_DONT_MIME |
|
This message is not MIME-able. |
|
EF_DISCARD |
|
Discard this message. |
|
EF_TOOBIG |
|
This message’s body is too big. |
|
EF_SPLIT |
|
This envelope has been split. |
|
EF_UNSAFE |
|
Message read from an untrusted source. |
For example, if the message were fully queued and required a DSN return receipt, the flags would print as:
e_flags=12<INQUEUE,SENDRECEIPT>
Note that this line of output is also produced by the
-d13.1,
-d40.3, and
-d50.1
debugging switches but under different
circumstances.
Show file descriptors with dumpfd( ) Debug command-line switch
The -d2.9 debugging
switch tells sendmail to
display the properties of each open file descriptor.
That output is produced by the
dumpfd( ) routine, and each
line of output is for a single file
descriptor:
number: fl=flags mode=mode type stats
Here, the number is the count of the open file descriptor. Note that descriptors 0, 1, and 2 are usually tied to the standard input, output, and error output, respectively.
The flags is a hexadecimal representation of the state flags associated with a file descriptor. F_GETFL is used with ioctl(2) to fetch each, and all are described in <sys/fcntl.h> on most systems.
The mode is printed in octal and is the st_mode associated with an fstat(2) of the file descriptor.
The type examines the file type portion of the st_mode and prints SOCK for a socket, CHR: for a character special device, BLK: for a block special device, FIFO: for a named pipe, DIR: for a directory, LNK: for a symbolic link, and nothing otherwise (e.g., nothing if it is a file).
The stats are printed for all but the socket. They look like this:
dev=major/minor ino=inum nlink=nlink u/gid=user-id/group-id size=bytes
Here the dev= shows
the major and minor device numbers for the device
that the file descriptor is associated with. The
inum is the inode number on
the disk (if there is one) and
nlink is the number of hard
links to the file on disk. The u/gid shows the user and
group ownership associated with the file descriptor.
The bytes is the number of
bytes in a file, and zero for almost everything
else.
For a socket, the stats part of each line looks like this:
[addr]/port-> host
Here, addr is the IP address
(surrounded in square braces) of the local end of
the socket. If the connection is of type AF_INET or
AF_INET6, the port number of the connection is also
shown as /port. The
host is the hostname, as
returned by getpeername(3), of
the connecting host. If any of these cannot be
found, the error string associated with
errno is printed
parenthetically in its place.
The -d7.9, -d40.9, and -d46.9 debugging
switches also print a line such as this for specific
file descriptors. Also, if
sendmail is run with the
-d10.100
switch, or if sendmail fails to
open a tf queue
file (The Temporary qf Rewrite Image: tf on page 400) or if sendmail
exited because of too many open files, it will
syslog all its open file
descriptors within this format.
Trace enoughspace( ) Debug command-line switch
The MinFreeBlocks
option (MinFreeBlocks on page
1057) defines the minimum number of disk blocks that
must be reserved on the queue disk. If an incoming
SMTP message will fill the disk beyond this minimum,
the message is rejected.
The -d4.80
debugging switch[225] traces the
enoughspace( ) routine in
conf.c. That routine examines
the disk space and prints the following if the
MinFreeBlocks
option (MinFreeBlocks on page
1057) was less than or equal to zero, or if the
message’s size is less than or equal to zero:
enoughdiskspace: no threshold
Show failed mail Debug command-line switch
Mail can fail for a wide variety of reasons. The way
that sendmail handles errors is
determined by the setting of the ErrorMode option (ErrorMode on page 1028) in the
configuration file. The -d6.1 (a.k.a. -d6) debugging switch causes
sendmail to print the
error-handling mode that is in effect at the time it
first begins to handle failed mail:
savemail, errorMode = char, id = qid, ExitStat = errornum e_from= ← output of printaddr( ) here (§15.3 on page 533)
Here, char is either p for print errors;
m for mail-back
errors; w for
write-back errors; e for special Berknet processing; or
q for “don’t
print anything” (all of which are described under
the ErrorMode
option in ErrorMode on page 1028).
The qid is the queue identifier
(such as g7PEf0Bv027517). The
errornum is the number of the
error that caused the message to fail (as defined in
<sysexits.h>). And
e_from= uses
printaddr( ) to print details
about the sender’s address.
If the error-processing mode is m (for mail back) and
the -d6.1
debugging switch is in effect,
sendmail prints details about
how the message is being returned to the
sender:
***Return To Sender: msg=reason, depth=number, e=addr, returnq= ← output of printaddr( ) here (§15.3 on page 533)
Here, reason is a quoted string
of text that explains why the mail failed. This can
be an SMTP reply string. The
number is zero for normal
delivery and one for error delivery. The
addr is the location in
memory of the information about the current
envelope. Finally, sendmail
calls printaddr( ) to print the
details of the queue of recipients (returnq=) for the
current message.
DNS name resolution Debug command-line switch
Name resolution is the process of determining a machine’s IP address based on its fully qualified domain name. This is done by using the Domain Name System (DNS). The process that sendmail uses to resolve a name is described in How sendmail Uses DNS on page 325.
When sendmail finds that a
hostname is really an MX record, it attempts to look
up the address (which can be an A or AAAA record)
for the host that handles mail receipt. That request
can fail for a variety of reasons. If the -d8.1 (a.k.a. -d8) debugging switch is
specified, sendmail produces
the following message:
getmxrr: res_search(host) failed (errno=errornum, h_errno=herrornum )
Here, host is the hostname that was looked up, errornum is the system error number (if any) from <errno.h>, and herrornum is the resolver-specific error number from <netdb.h>, as shown in Table 15-6.
|
Value |
Mnemonic |
Description |
|
−1 |
NETDB_INTERNAL |
Error in the lookup code, see |
|
0 |
NETDB_SUCCESS |
Success |
|
1 |
HOST_NOT_FOUND |
Host not found |
|
2 |
TRY_AGAIN |
Temporary DNS server failure |
|
3 |
NO_RECOVERY |
Nonrecoverable errors and refusals |
|
4 |
NO_DATA |
Valid name but no record of requested type |
Call to getcanonname(3) Debug command-line switch
The routine dns_getcanonname( )
in domain.c of the
sendmail source converts a
hostname to a fully qualified domain name. This
routine is called only if DNS is used to look up
hostnames, as determined by the ResolverOptions option
(ResolverOptions on page 1080)
and the ServiceSwitchFile option (ServiceSwitchFile on page 1088). If it
is, dns_getcanonname( ) can be
called from three places: during startup to get the
values for $w,
$j, and
$m (-d0.4 on page 542); when a host is
looked up via the $[ and $] canonify operators (Canonicalize Hostname: $[ and $] on page 668); or when a host is looked up using
the host database
map (host on page 910).
The -d8.2 debugging
switch shows the hostname before it is fully
qualified with this call:
dns_getcanonname(host, flag)
If the flag is nonzero, calls to the getmxrr( ) routine (which looks up MX records) are also traced. On entry to that routine, sendmail will print:
getmxrr(host, droplocalhost=bool)
The host is the hostname whose MX
records are being looked up. The
bool, if nonzero, means that
all MX records that are less preferred than the
local host (as determined by $=w) will be discarded.
If zero, they will be retained.
The -d8.2 debugging
switch also causes sendmail to
show the result of processing the ResolverOptions option’s
settings (ResolverOptions on page
1080) while reading the configuration file:
_res.options = hex, HasWildcardMX = 1 or 0
The hex is a hexadecimal
representation of the state structure’s options variable as
described in <resolv.h>.
The value of HasWildcardMX is determined by its
prefix (+ or
−) when listed
with the ResolverOptions option.
Trace dropped local hostnames Debug command-line switch
If a hostname is dropped because
bool (above) is nonzero, the
-d8.3 switch
causes sendmail to print the
following:
found localhost (host) in MX list, pref=pref
The host is the hostname that is being dropped. The pref is the numerical preference associated with the MX record.
Hostname being tried in getcanonname(3) Debug command-line switch
The -d8.5 debugging
switch causes the
getcanonname(3) routine to
print the host name it is trying to fully qualify.
It shows the name with the local domain appended,
without the local domain appended, and at each step
in between. Each try is printed as:
dns_getcanonname: trying host.domain (type)
Here, the type is the type of lookup and is either A, AAAA, or MX. (Prior to V8.12, the type could also include ANY.)
Yes/no response to -d8.5 Debug command-line switch
The -d8.7 debugging
switch causes sendmail to print
a yes or no response to each of the “trying” lines
printed by −8.5.
“Yes” means that the host could
successfully be fully canonicalized. A yes answer
prints just this:
YES
If the host could not be canonicalized, a more complex answer is printed:
NO: errno=errornum, h_errno=herrornum
The errornum is the system error number (if any) from <errno.h>, and herrornum is the resolver-specific error from <netdb.h>, as shown in Table 15-6.
Resolver debugging Debug command-line switch
The -d8.8 debugging
switch causes the resolver library to be put into
debugging mode (if that mode was included when that
library was compiled). The ResolverOptions option (ResolverOptions on page 1080) +DEBUG
also turns on this debugging mode. But be aware that
turning on +DEBUG will cause a large number of
screens full of output to be produced by the
resolver library for every DNS lookup.
If the name server returns an answer to an MX lookup,
and if the answer is not an MX record or an error,
sendmail will skip that host.
The -d8.8
debugging switch (or the resolver library being in
debug mode) then causes
sendmail to print the
following:
unexpected answer type wrongtype, size bytes
The wrongtype is an integer that can be found in <arpa/nameser.h >.
Trace delivery Debug command-line switch
The -d11.1 (a.k.a.
-d11) debugging
switch is used to trace message delivery. It must be
run with the -v
command-line switch, or no output will be
produced.
First, for each delivery agent the following is printed:
openmailer: argvHere, argv is the A= array for the
delivery agent, with macros expanded and
printed.
Second, the status of remote hosts is cached
internally. Before connecting to a remote host,
sendmail checks its cache to
see whether that host is down. If it is, it skips
connecting to that host. If the -d11.1 debugging switch
is also specified, the status of the down host is
printed as:
openmailer: output of mci_dump( ) hereThe output of mci_dump( ) looks like this:
MCI@memaddr: flags=mci_flags<flag,flag,...>,
errno=mci_errno, herrno=mci_herrno, exitstat=mci_exitstat, state=mci_state,
pid=mci_pid,
maxsize=mci_maxsize, phase=mci_phase, mailer=mci_mailer,
status=mci_status, rstatus=mci+rstatus,
host=mci_host, lastuse=mci_lastuseThe meaning of each mci_ item in this output is described in Table 15-7.
|
Name |
What prints |
|
memaddr |
The address in memory of this C-language structure |
|
mci_flags |
The flag bits in hexadecimal (see Table 15-8) |
|
mci_errno |
The error number of the last connection |
|
mci_herrno |
The DNS |
|
mci_exitstat |
The <sysexits.h> exit status of the last connection |
|
mci_state |
The current SMTP state |
|
mci_maxsize |
The maximum size message the host will accept |
|
mci_pid |
The PID of the child process |
|
mci_phase |
SMTP phase (string) such as “client greeting” (or NULL) |
|
mci_mailer |
The (text) name of the delivery agent (or NULL) |
|
mci_status |
The DSN status to be added to the address (or NULL) |
|
mci_rstatus |
The SMTP status to be added to the address (or NULL) |
|
mci_host |
The host’s name (or NULL) |
|
mci_lastuse |
Last usage time in ctime(3) format |
Table 15-8 shows what the individual flag bits in
mci_flags mean, and the
human-readable flags text that
corresponds to each bit. Those text items are shown
with the leading source MCIF_ prefix removed.
|
Name printed |
Hex value |
Meaning |
|
VALID |
0x00000001 |
This entry is valid. |
|
TEMP |
0x00000002 |
Don’t cache this connection (prior to V8.12). |
|
CACHED |
0x00000004 |
This connection is currently in open cache. |
|
ESMTP |
0x00000008 |
This host speaks ESMTP. |
|
EXPN |
0x00000010 |
EXPN command supported. |
|
SIZE |
0x00000020 |
SIZE option supported. |
|
8BITMIME |
0x00000040 |
BODY=8BITMIME supported. |
|
7BIT |
0x00000080 |
Strip this message to 7 bits. |
|
MULTSTAT |
0x00000100 |
MAIL11V3: handles MULT status (prior to V8.12). |
|
INHEADER |
0x00000200 |
Currently outputting header. |
|
CVT8TO7 |
0x00000400 |
Convert from 8 to 7 bits. |
|
DSN |
0x00000800 |
DSN extension supported. |
|
8BITOK |
0x00001000 |
OK to send 8-bit characters. |
|
CVT7TO8 |
0x00002000 |
Convert from 7 to 8 bits. |
|
INMIME |
0x00004000 |
Currently reading MIME header. |
|
AUTH |
0x00008000 |
ESMTP AUTH= is supported (V8.10 and above). |
|
AUTHACT |
0x00010000 |
SASL (AUTH) is active (V8.10 and above). |
|
ENHSTAT |
0x00020000 |
ENHANCEDSTATUSCODES SMTP extension supported (V8.10 and above). |
|
PIPELINED |
0x00040000 |
PIPELINING SMTP extension supported (V8.12 and above). |
|
TLS |
0x00100000 |
STARTTLS SMTP extension supported (V8.12 and above). |
|
TLSACT |
0x00200000 |
STARTTLS is active (V8.12 and above). |
|
DLVR_BY |
0x00400000 |
DELIVERBY SMTP extension supported (V8.12 and above). |
|
HELO |
0x00800000 |
Sending sendmail used HELO, so ignore extensions (V8.12 and above). |
|
ONLY_EHLO |
0x10000000 |
Use only EHLO when establishing a connection (V8.12 and above). |
After checking to see whether the host is down,
sendmail attempts to connect
to it for network SMTP mail. If that connect fails,
the -d11.1
debugging switch causes the following to be
printed:
openmailer: makeconnection => stat=exitstatus, errno=errno
Here, exitstatus is a numerical representation of the reason for the failure, as documented in <sysexits.h>, and errno is the system-level reason for the error, as documented in <errno.h>.
Other errors, such as failure to establish a pipe(2), or failure to fork(2), cause the following to be printed:
openmailer: NULL
This message (although it contains no information) signals that a more descriptive error message was logged with syslog(3) (Log with syslog on page 513).
Show the user-id running as during delivery Debug command-line switch
To perform delivery, sendmail
often has to set its uid to
something other than root’s.
The logic behind that process is described in Delivery to Files on page 466. The
-d11.2
debugging switch tells sendmail
to print the real and effective
user-ids that it is running
under during delivery:
openmailer: running as r/euid=real-user-id/effective-user-idAlso, the -d11.2
debugging switch causes
sendmail to print any error
response that might be produced by a delivery
agent:
giveresponse: stat=status, e->e_message=what
Here, status is the number of the error that caused delivery to fail (or succeed if it is 0) as defined in <sysexits.h>. The what is either the error message produced by the delivery agent, or <NULL> if the delivery agent was silent.
Show mapping of relative host Debug command-line switch
In the SMTP RCPT command, sendmail is required to express the recipient’s address relative to the local host. For domain addresses, this simply means that the address should be RFC2821-compliant.
The -d12.1 (a.k.a.
-d12) debugging
switch causes sendmail to print
the address as it appeared before it was made
relative:
remotename(addr)If the addr is for the sender or
recipient and is being processed from a queue file,
nothing more is printed, and the
addr is processed by canonify rule set 3. If
the delivery agent for the recipient has the
F=C flag set
(F=C on page 768) and
the recipient address lacks a domain part, the
domain of the sender is appended, and the result is
processed by the canonify rule set 3 again.
Sender/recipient-specific rule sets are then applied
(1 and S= for the sender, or
2 and R= for the recipient).
Next, the final
rule set 4 is applied, and any
sendmail macros in the result
are expanded. Finally, the fully qualified and
relative address is printed as:
remotename => `addr'Show delivery Debug command-line switch
The -d13.1 (a.k.a.
-d13) debugging
switch causes sendmail to
display information about the recipients of each
mail message as it is being delivered. The -d13.1 debugging switch
tells sendmail to print the
mode of delivery and then the recipient
information:
SENDALL: mode dmode, id=qid, e_from output of printaddr( ) here (§15.3 on page 533) e_flags = envelope flags here sendqueue: output of printaddr( ) here (§15.3 on page 533)
Here, dmode is one of the
delivery modes shown in Table 15-9. The qid is the queue
message identifier (such as g7PI04TK027759). The
address of the sender (e_from) is dumped by using the
printaddr( ) routine. Then
the envelope flags (e_flags) are dumped as described in
Table 15-5 on
page 545. Next, information about all the recipients
(sendqueue:) is
printed by using the printaddr(
) routine.
|
Mode |
Description |
|
|
Deliver in background |
|
|
Defer, queue without DNS lookups |
|
|
Interactive delivery |
|
|
Queue, don’t deliver |
|
|
Verify only (used internally) |
Finally, the -d13.1
debugging switch causes
sendmail to print a message
every time it splits an envelope in two:
sendall: split orig into new
Here, orig is the original queue message identifier for the original envelope (such as g7PKuBWE027877) and new is the identifier for the new envelope, the near identical clone of the first. Envelopes need to split if they have different owners.
Show resolving delivery agent: parseaddr( ) Debug command-line switch
The -d20.1 (a.k.a.
-d20) debugging
switch causes sendmail to print
each recipient address before it is rewritten by the
canonify rule
set 3 and the parse rule set 0:
--parseaddr(addr)Here, addr is the recipient address before it is rewritten and before any aliasing has been performed on it.
The -d20.1
debugging switch also causes
sendmail to print information
about problems that might exist in recipient
addresses. If an address contains any control or
whitespace character that is not an
isspace(3) character,
sendmail prints the following
message and skips that address:
parseaddr-->bad addressIf an address is empty (that is, if it is composed entirely of an RFC2822-style comment), sendmail prints the following and skips that address:
parseaddr-->NULL
After the recipient address has been rewritten by the
canonify rule
set 3 and the parse rule set 0, and if a delivery
agent was successfully selected,
sendmail prints the result
using the printaddr( )
routine.
Trace rewriting rules Debug command-line switch
The -d21.1 (a.k.a.
-d21) debugging
switch causes sendmail to print
each step that it takes in rewriting addresses with
rules. The -d21.1
debugging switch causes output to be produced that
is identical to the output produced by the -bt command-line switch
(Overview on page 299):
rewrite: rule set name or number input: address rewrite: rule set name or number returns: address
First, the address (workspace) is displayed for the rule set whose name or number is shown before rewriting, and second, the address is shown after rewriting.
Because rules are recursive by nature, they can sometimes cause infinite loops (Rewrite Once Prefix: $: on page 662). When a rule loops more than 100 times, the following error is issued:
Infinite loop in rule set name or number, rule rule number
If the -d21.1
debugging switch was also invoked, the preceding
error is followed by:
workspace: state of rewritten address, so far, is shown hereTrace $& macros Debug command-line switch
The -d21.2
debugging switch tells sendmail
to show the current value of any deferred-expansion
macro (one that was declared with the $& prefix). Each
such macro that is encountered in processing a rule
prints as:
rewrite: LHS $&char => "value" rewrite: RHS $&char => "value" rewrite: LHS $&name => "value" ← V8.7 and above rewrite: RHS $&name => "value" ← V8.7 and above
The char is the single-character
name of the macro, the name is
either a multicharacter macro name or a
single-character name, and the
value is its current value.
If that particular macro lacks a value, it will
print as (NULL). The LHS refers to the lefthand side of the
rule, and the RHS
corresponds to the righthand side.
Deferred-expansion macros are described in Use Value As Is with $& on page
793.
Trace tokenizing an address: prescan( ) Debug command-line switch
Processing of rules requires that all addresses be
divided into tokens. The -d22.1 (a.k.a. -d22) debugging switch causes
sendmail to print the various
steps it takes in tokenizing an address.
In addition to tokenizing, the prescan( ) routine also normalizes addresses. That is, it removes RFC2822-style comments and recognizes quoted strings. Be aware that rules are also viewed as addresses and processed by prescan( ) when the configuration file is being read.
The -d22.1
debugging switch tells sendmail
to complain if the first token in the address it is
parsing turns out to be nothing:
prescan: null leading token
This can happen if an address (or rule) contains only RFC2822-style comments in parentheses.
Show address before prescan Debug command-line switch
The -d22.11
debugging switch causes the address to be printed as
it appears before any tokenizing or
normalization:
prescan: addressShow address after prescan Debug command-line switch
The -d22.12
debugging switch causes the address to be printed as
it appears after all tokenizing and
normalization:
prescan= => addressTrace “sendtolist” Debug command-line switch
Each recipient address for a mail message is added one
by one to an internal list of recipients. The
-d25.1 (a.k.a.
-d25) debugging
switch causes sendmail to print
each address as it is added to this list:
sendto: list ctladdr= output of printaddr( ) here (§15.3 on page 533)
After each is added, those that have selected a
delivery agent with the F=A (F=A
on page 767) and F=w (F=w on
page 781) flags set are further processed by
aliasing and by reading the user’s
~/.forward file. Each new
address that results from this processing is added
to the list, and any duplicates
are discarded.
Trace recipient queueing Debug command-line switch
The -d26.1 (a.k.a.
-d26) debugging
switch causes sendmail to print
the addresses of recipients as they are added to the
send queue, which is an
internal list of addresses that
sendmail uses to sort and
remove duplicates from the recipient addresses for a
mail message.
On entry to the recipient( )
routine, the -d26.1 debugging switch causes
sendmail to print the raw
address (as it appears before adding it to the send
queue):
recipient (level): output of printaddr( ) here (§15.3 on page 533)
An address can be the result of alias expansion.
Because the process of aliasing (including :include: and
.forward files) can be
recursive, it is possible to get too many alias
expansions. The level shows the
number of alias expansions so far. If that number
exceeds the value set by the MaxAliasRecursion option
(MaxAliasRecursion on page
1044), sendmail issues this
warning:
aliasing/forwarding loop broken (level aliases deep; maximum max)
Next, sendmail compares the new address to others that are already in the send queue. If it finds a duplicate, it prints the following message and skips the new address:
addr in sendq: output of printaddr( ) here (§15.3 on page 533)
Here, addr is the duplicate address. Information about that address is produced with the printaddr( ) routine.
Trace aliasing Debug command-line switch
The -d27.1 (a.k.a.
-d27) debugging
switch causes sendmail to print
each step it takes when processing local addresses
through aliasing. First,
sendmail prints the addresses
being aliased:
alias(addr)Here, addr is the address (usually a local username) that is about to be aliased. Note that it can already be the result of previous aliasing. If the addr can be aliased, its transformation is printed as:
addr (host, user) aliased to newaddr
Here, addr is the address before aliasing, and the newaddr is the new address that resulted from successful aliasing. The host and user are the hostname and username from the recipient part of the envelope. If the addr cannot be aliased, nothing is printed.
During initialization, if the
aliases database cannot be
opened, the -d27.1 debugging switch causes
sendmail to print:
Can't open aliasfileHere, aliasfile is the full
pathname of the aliases(5)
file, as declared by the AliasFile option (AliasFile on page 970) or implied with
the service-switch file set by the ServiceSwitchFile option
(ServiceSwitchFile on page
1088).
If the failure was due to a faulty map declaration, sendmail logs the following error:
setalias: unknown alias class dbtypeIf the map is not allowed to provide alias services, sendmail logs this error:
setalias: map class dbtype can't handle aliasesIf sendmail is trying to create a
database file and it can’t (usually when it is run
with the -bi
command-line switch or run as
newaliases), the -d27.1 debugging switch
causes the following error to be printed:
Can't create database for filename: reason here
A self-destructive alias can cause a dangerous loop to occur. For example, the following two aliases can lead to a loop on the host mailhost:
jake: Jake_Bair Jake_Bair: jake@mailhost
The -d27.1
debugging switch causes the following message to be
printed when sendmail tests an
address to see whether it loops:
self_reference(addr) ... no self ref ← if it didn't loop ... cannot break loop for "addr" ← if it's unbreakable
An alias loop is unbreakable if no local username can be found in the list of aliases.
The -d27.1
debugging switch also causes
sendmail to print a warning
if it cannot open an alias file for rebuilding (the
AutoRebuildAliases option, AutoRebuildAliases on page
978):
Can't open file: reason here newaliases: cannot open file: reason here
Here, the error might be caused by the file simply not existing (as would be the case if it was NFS-mounted on a down host) or an I/O error (as would be the case if it was a bad disk):
warning: cannot lock file: reason hereFailure to lock can be caused by system errors or by the file being read-only. Note that maintaining an aliases file under revision control can cause a read-only copy to exist, resulting in the following error:
Can't create database for file: reason here Cannot create database for alias file file
This error indicates that the output file (the dbm(3) or db(3) file) could not be created or written.
The -d27.1
debugging switch also causes
sendmail to print the
following message when it is attempting to read the
user’s ~/.forward file:
forward(user)If the user has no home directory listed in the passwd(5) file, sendmail issues the following message with a syslog(3) level of LOG_CRIT:
forward: no home
Include file, self reference, error on home Debug command-line switch
The -d27.2
debugging switch causes each :include: and ~/.forward file name to
be printed before each is opened for reading:
include(file)The -d27.2
debugging switch also causes additional information
to be printed for the alias loop check described
earlier:
self_reference(addr) ... getpwnam(user)...found ← if in passwd file ... getpwnam(user)...failed ← otherwise
The -d27.2
debugging switch also causes
sendmail to print a message
every time it sleeps while waiting for the
aliases database to be
rebuilt:
aliaswait: sleeping for secs secondsAlso, when processing the
~/.forward file,
sendmail might experience a
temporary inability to read it (such as when an NFS
server is down). In that case the -d27.2 debugging switch
causes the following message to be printed:
forward: transient error on homeHere the message will be queued and tried again later.
Forwarding path and alias wait Debug command-line switch
The -d27.3
debugging switch causes each path for a possible
~/.forward
file to be printed before it is tried:
forward: trying fileHere, file is each file in the
path of files declared by the ForwardPath option
(ForwardPath on page
1034).
The -d27.3
debugging switch also causes
sendmail to trace its wait
for another alias rebuild to complete (Rebuild the Alias Database on page
478). First sendmail prints the
database type (such as hash) and filename for which it will
wait:
aliaswait(dbtype:file)If the database is not rebuildable (as would be the
case with a network database type, such as
nis,
nis+, or hesiod), the -d27.3 debugging switch
causes the following to be printed:
aliaswait: not rebuildable
If the file specified doesn’t
exist, the -d27.3
debugging switch prints:
aliaswait: no source file
The -d27.3
debugging switch also causes
sendmail to print an error
message if there was a read error while processing
an :include: or
~/.forward
file:
include: read error: reason herePrint not safe Debug command-line switch
A ~/.forward file must be owned
by the user or by root. If it
is not, it is considered unsafe, and
sendmail ignores it. The
-d27.4
debugging switch causes
sendmail to print a message
describing any such file it finds unsafe:
include: not safe (uid=user-id)Note that a file is considered unsafe if, among other things, it lacks all read permissions.
The -d27.4
debugging switch also causes
sendmail to print information
about an :include: file beyond that printed with
-d27.2:
include(file) ← printed with -d27.2 ruid=real-user-id euid=effective-user-id ← printed with -d27.4
This shows the real user-id (the
ruid=) and
effective user-id (the euid=) of the currently
running sendmail.
The -d27.4
debugging switch causes
sendmail to print an error if
an :include: or
~/.forward file cannot be
opened for reading:
include: open: reason hereTrace aliasing with printaddr( ) Debug command-line switch
The -d27.5
debugging switch tells sendmail
to print several addresses with
printaddr( ) (Interpret the Output on page 533) as
each one is handled.
When an address is aliased to another, the original
needs to be marked as one that shouldn’t be
delivered. The QS_DONTSEND here means just
that:
alias: QS_DONTSEND output of printaddr( ) here (§15.3 on page 533)
If there was a self-reference, the retained address is printed like this:
sendtolist: QS_SELFREF output of printaddr( ) here (§15.3 on page 533)
If the original (before the test for a self-reference) is not the same as the retained address, the original must be marked for nondelivery:
sendtolist: QS_DONTSEND output of printaddr( ) here (§15.3 on page 533)
If an address resulted from an :include: or
~/.forward file, it will have
a controlling user associated with it. That
controlling user’s address needs to be marked for
nondelivery:
include: QS_DONTSEND output of printaddr( ) here (§15.3 on page 533)
Show setting up an alias map Debug command-line switch
The -d27.8
debugging switch tells sendmail
to print the string passed to its internal
setalias( ) routine:
setalias(what)Here, what is one of the items
listed with the AliasFile option (AliasFile on page 970) such as
/etc/mail/aliases, or implied
with the service-switch file and the ServiceSwitchFile option
(ServiceSwitchFile on page
1088).
Show user-id/group-id changes with :include: reads Debug command-line switch
The -d27.9
debugging switch causes
sendmail to trace the setting
and resetting of its user-id
and group-id identities when
processing :include: and
~/.forward files. First, an
additional line is printed below the output of the
-d27.2 and
-d27.4
debugging switches:
include(file) ← printed with -d27.2 ruid=real-user-id euid=effective-user-id ← printed with -d27.4 include: old uid = real-user-id/effective-user-id
The second and third lines contain the same
information. After the new line is printed,
sendmail might or might not
change its identity depending on the nature of a
:include: or
~/.forward file and that
file’s controlling user. Regardless of whether it
changed, sendmail
prints:
include: new uid = real-user-id/effective-user-idAfter sendmail has finished
processing an :include: or
~/.forward file, it resets
its user-id and
group-id back to their
original values and displays the result:
include: reset uid = real-user-id/effective-user-idTrace user database transactions Debug command-line switch
The sendmail program can be
compiled to use the user database (userdb on page 942) by defining
USERDB in the Makefile (USERDB on page 150). If an address is
selected by the parse rule set 0 for delivery by a
delivery agent with the F=l flag set, and if it remains
un-aliased even if the F=A flag is set and if the F=5 (F=5 on page 764) delivery agent
flag is set, it is looked up in the user database.
The -d28.1
(a.k.a. -d28)
debugging switch is used to watch the interaction
between sendmail and the user
database:
udbexpand(addr)Here, addr is the address being looked up.
The sender is looked up in a similar fashion. The intent in this case is to correct information such as the return address:
udbmatch(login, what)
Here, login is the login name of
the sender and what is the
mailname for
sender lookups. If the lookup is via hesiod,
sendmail will print the same
information, like this:
hes_udb_get(login, what)
If the sender is found in the database, sendmail prints:
udbmatch = => login@defaulthostHere, login can be a new login name. The defaulthost is either the sitewide host for all reply mail as defined in the user database, or the default destination host for a particular user.
In the event that a db(3)-style
user database fails to open, the -d28.1 debugging switch
displays the following error message:
dbopen(database): reason for failure here
Special rewrite of local recipient Debug command-line switch
With a level 2 or greater configuration file (see the
V configuration
command in The V Configuration Command on page
580), V8 sendmail passes the
user part ($u) of
local recipient addresses through the localaddr rule set 5 as
a hook to select a new delivery agent. If the
F=5 flag (F=5 on page 764) is set for the
delivery agent, the localaddr rule set 5 is called after
all aliasing (including the
~/.forward file). The
-d29.1 (a.k.a.
-d29) debugging
switch causes the address to be printed as it
appears before the localaddr rule set 5 rewrite:
maplocaluser: output of printaddr( ) here (§15.3 on page 533)
Information about the address is printed with the
printaddr( ) routine. The
output of maplocaluser( )
becomes the input to recipient(
), so the result of rewriting can be seen by using
the -d26.1
debugging switch (-d26.1 on page
555) in combination with this one.
Trace fuzzy matching Debug command-line switch
Fuzzy matching is the attempt to match a local
recipient name to one of the names in the GECOS
field of the passwd(5) file (or
NIS map). The -d29.4 debugging switch causes the
process of fuzzy matching to be traced:
finduser(name)Here, name is an address in the form of a local user address, without the host part. The name is first looked up in the passwd(5) file on the assumption that it is a login name. If it is found, sendmail prints:
found (non-fuzzy)
If sendmail was compiled with
hesiod support,
all numeric login names will not work properly,
resulting in the following:
failed (numeric input)
If the name is looked up and not found, the entire
passwd(5) is searched to see
whether name appears in any of
the GECOS fields. This search is done only if
MATCHGECOS (MATCHGECOS on page
120) was defined when sendmail
was compiled and if the MatchGECOS option (MatchGECOS on page 1043) is true.
If MATCHGECOS was undefined, the search ends and the
not-found name causes the mail
to bounce. If the MatchGECOS option is false,
sendmail bounces the message
and prints the following:
not found (fuzzy disabled)
If the MatchGECOS
option is true, the GECOS fields are searched. But
before the search starts, any underscore characters
(and the character defined by the BlankSub option, BlankSub on page 980) that appear in
name are converted to spaces.
Then, in turn, each GECOS field has the full name
extracted (everything following the first comma,
semicolon, or percent is truncated off, including
that character), and any "&" (ampersand) characters found
are converted to the login name. The two are then
compared in a case-insensitive fashion. If they are
identical, sendmail
prints:
fuzzy matches found GECOS field hereIf all GECOS fields are compared and no match is found, sendmail bounces the message and prints the following:
no fuzzy match found
There is no debugging flag to watch each comparison.
Trace processing of headers Debug command-line switch
Header lines (Overview on page 1120) from the configuration file and from mail messages are processed by the chompheader( ) routine before they are included in any mail message. That routine parses each header line to save critical information, to check for validity, and to replace default values with new values.
The -d31.2
debugging switch[226] shows that sendmail
is about to check whether it should replace a
From: or
Resent-From:
header with the one defined by the H configuration command.
If the header line is not read from the
configuration file and if
sendmail is not processing
the queue, the following test is made:
comparing header from (header) against default (address or name)
The value of the From: or Resent-From:
header is compared to the
sender’s address and to the
sender’s name. If it is the
same as either one, the address is replaced.
Watch header assembly for output Debug command-line switch
When sendmail bounces a mail
message, it needs to create headers that probably
didn’t exist before. It uses the
putheader( ) routine to
create them. The -d34.1 (a.k.a. -d34) debugging switch causes
sendmail to print the
following on entry to that routine:
--- putheader, mailer = agent ---
Here, agent is the symbolic name of the delivery agent that will deliver the bounced message.
Trace header generation and skipping Debug command-line switch
Each header line created for the bounced message is displayed with two leading spaces. For example:
--- putheader, mailer = *file* ---
Return-Path: youThen certain headers are excluded from the bounced mail message header. Those with the H_CTE flag set (H_CTE Header Flag (V8.7 and Later) on page 1140) and either the MCIF_CVT8TO7 or MCIF_INMIME mci flag set will have the text:
(skipped (content-transfer-encoding))
appended and that header will be skipped (excluded).
Any header that has both the H_CHECK and H_ACHECK flags set and doesn’t have identical delivery agent flags set for itself and its cached connection information will also be skipped:
(skipped)
All re-sent headers (those marked with H_RESENT) are also skipped:
(skipped (resent))
Return-receipt headers are also skipped:
(skipped (receipt))
If a Bcc: header
(Bcc: on page 1152) is
being skipped, this is printed:
(skipped -- bcc)
Finally, valueless headers are also skipped with this message:
(skipped -- null value)
Any headers that survive this skipping process are included in the eventually delivered bounced message. Note that MIME headers are not generated or displayed here.
Macro values defined Debug command-line switch
The -d35.9
debugging switch[227] causes sendmail to
print each macro as it is defined. The output looks
like this:
define(name as "value")
Here, the name is the macro’s name, and the value is the value (text) assigned to the macro. If the macro already has a value assigned to it, sendmail prints:
redefine(name as "value")
Trace setting of options Debug command-line switch
Options can be set on the command line or in the
configuration file. The -d37.1 (a.k.a. -d37) debugging switch allows you to
watch each option being defined. As each is
processed, this message is first printed, without a
trailing newline:
setoption: name (char).sub =valHere, name is the option’s multicharacter name, char is its single-character equivalent (or a hexadecimal value if it is non-ASCII), and sub is the subvalue for that option if there was one. Finally, val is the value being given to that option. If the option has already been set from the command line and is thus prohibited from being set in the configuration file, sendmail prints:
(ignored)
A newline is then printed, and the job is done. If defining the option is permitted, sendmail next checks to see whether it is safe (Options That Are Safe on page 951). If it is not, sendmail prints:
(unsafe)
If it is unsafe, sendmail checks to see whether it should relinquish its current privileges. If so, it prints:
(Resetting uid)
A newline is then printed, and the option has been defined.
The -d37.1
debugging switch also shows the modifier flags set
for each DaemonPortOptions option. For example,
consider the following:
setoption DaemonPortOptions (O)=Name=MTA Daemon MTA flags: setoption DaemonPortOptions (O)=Port=587, Name=MSA, M=E Daemon MSA flags: NOETRN
The first setting of the DaemonPortOptions option sets no
modifier flags, so the line following it shows no
flags. The second setting of the DaemonPortOptions option
sets the M=E
modifier flag. The line following it shows that flag
means to disallow ETRN. See DaemonPortOptions on page 993 for the
meaning of the various possible modifier
flags.
Trace adding of words to a class Debug command-line switch
The adding of words to a class (C or F configuration
commands) can be traced with the -d37.8 debugging switch.
Each word is printed like this:
setclass(name, text)The text is added to the class whose symbolic name is name. Class names can be single-character or multicharacter (Class Configuration Commands on page 854).
Show database map opens and failures Debug command-line switch
Most database maps are declared directly with the
K configuration
command (The K Configuration Command on page 882). Others are declared internally by
sendmail, such as the
host and
alias maps. The
-d38.2
debugging switch (there is no -d38.1 information)
first shows database maps being initialized:
map_init(dbtype:name, file, pass)Here, dbtype is one of the
internal database types allowed by
sendmail, such as host, and dequote (The K Configuration Command on page
882, the K
configuration command). The
name is either the name you
gave to the database map with the K configuration command,
or one assigned internally by
sendmail (such as
aliases.files). The
file is either a literal
NULL, or the name of the database file (such as
/etc/mail/aliases). And
pass is a flag that tells
sendmail whether it should
open the database, rebuild the database, or do
neither.
Next, the -d38.2
debugging switch causes
sendmail to show each
database map as it is about to be opened. The output
that is produced will look like one of the following
lines:
bt_map_open(name, file, mode) hash_map_open(name, file, mode) hes_map_open(name, file, mode) impl_map_open(name, file, mode) ldap_map_open(name, mode) ndbm_map_open(name, file, mode) ni_map_open(name, file, mode) nis_map_open(name, file, mode) nisplus_map_open(name, file, mode) stab_map_open(name, file, mode) switch_map_open(name, file, mode) text_map_open(name, file, mode) user_map_open(name, mode)
In all of the previous lines, the
mode is a decimal
representation of the file permissions that are used
during the open. The name prefixing each line
corresponds to the database type. For example,
impl
corresponds to the implicit database type.
The -d38.2
debugging switch also causes
sendmail to display the NIS
domain that was used if one was specified for the
nisplus
database type:
nisplus_map_open(file): using domain ypdomain
The -d38.2
debugging switch also allows other silent errors to
be printed about some open failures. Under NIS+,
lookups are performed by named columns (as in the
case of the password database, the columns are named
passwd,
shell, and so
on):
nisplus_map_open(name): cannot find key column colname nisplus_map_open(name): cannot find column colname
Text files that are used as maps must be declared with
a filename that is an absolute path (begins with a
/ character,
thus forming a fully qualified pathname), that
exists, and that is a regular file. If there is a
problem, one of the following is logged (even if
-d38.2 is not
specified):
text_map_open: filename required text_map_open(file): filename must be fully qualified text_map_open(name): cannot stat file text_map_open(name): file is not a file
Text files should be syntactically correct. The
delimiting character, char,
will print either as a single character or as the
phrase (whitespace). Note that the third line
in the following example will be reported only when
the -d38.2
debugging switch is used:
text_map_open(file): -k should specify a number, not badtext text_map_open(file): -v should specify a number, not badtext text_map_open(file): delimiter = char
Show passes Debug command-line switch
The sendmail program initializes
maps in passes so that it can open a map for reading
or rebuild. That is, pass 0 opens it for reading
only, and passes 1 and 2 open it for updating. This
gives sendmail the opportunity
to detect optional maps. The -d38.3 debugging switch
causes sendmail to print
wrong pass
every time it skips rebuilding because the pass is
inappropriate:
map_init(dbtype:name, file, pass) ← from -d38.2 wrong pass
The -d38.3
debugging switch also causes
sendmail to print a failure
message if an implicit database type does not
exist:
impl_map_open(name, file, mode) ← from -d38.2 no map file
Show result of database map open Debug command-line switch
When rebuilding the aliases
files, each database file is rebuilt even if its
source file has not changed. The -d38.4 debugging switch
shows the success or failure of each open:
map_init(dbtype:name, file, pass) ← from -d38.2 dbtype:name file valid or invalid
The status is valid
if the open succeeded; otherwise, it is invalid.
The -d38.4
debugging switch also shows each map being looked up
in a switch
database type (switch on page
938):
switch_map_open(name, file, mode) ← from -d38.2 map_stack[index] = dbtype:name
If the name was not declared in a
K configuration
command, the following error is printed:
Switch map dbtype: unknown member map name
Trace database map closings and appends Debug command-line switch
The -d38.9
debugging switch traces map closures for maps that
can be closed:
ndbm_map_close(name, file, flags) db_map_close(name, file, flags) impl_map_close(name, file, flags) ph_map_close(name): pmap-ph_fastclose=num prog_map_lookup(name) failed (errno) -- closing seq_map_close(name)
Here, the name is either the name
you gave to the map with the K configuration command,
or one assigned internally by
sendmail (such as
aliases.files). The
file is the filename on disk
that contains the database. The
flags describe the specific
features of a map. They are printed in hexadecimal,
and the meanings of the values printed are listed in
Table 15-10.
|
Hex |
Text |
Description |
|
MF_VALID |
0x00000001 |
This entry is valid. |
|
MF_INCLNULL |
0x00000002 |
Include null byte in key. |
|
MF_OPTIONAL |
0x00000004 |
Don’t complain if map is not found. |
|
MF_NOFOLDCASE |
0x00000008 |
Don’t fold case in keys. |
|
MF_MATCHONLY |
0x00000010 |
Only check for existence of the key. |
|
MF_OPEN |
0x00000020 |
This database is open. |
|
MF_WRITABLE |
0x00000040 |
Open for writing. |
|
MF_ALIAS |
0x00000080 |
This is an alias file. |
|
MF_TRY0NULL |
0x00000100 |
Try with no null byte. |
|
MF_TRY1NULL |
0x00000200 |
Try with the null byte. |
|
MF_LOCKED |
0x00000400 |
This map is currently locked. |
|
MF_ALIASWAIT |
0x00000800 |
Alias map in aliaswait state. |
|
MF_IMPL_HASH |
0x00001000 |
Implicit: underlying hash database. |
|
MF_IMPL_NDBM |
0x00002000 |
Implicit: underlying ndbm database. |
|
MF_UNSAFEDB |
0x00004000 |
This map is world-writable (prior to V8.12.1). |
|
MF_APPEND |
0x00008000 |
Append new entry on rebuild. |
|
MF_KEEPQUOTES |
0x00010000 |
Don’t dequote key before lookup. |
|
MF_NODEFER |
0x00020000 |
Don’t defer if map lookup fails (V8.8 and above). |
|
MF_REGEX_NOT |
0x00040000 |
Regular expression negation (V8.9 and above). |
|
MF_DEFER |
0x00080000 |
Don’t look up map in defer mode (V8.10 and above). |
|
MF_SINGLEMATCH |
0x00100000 |
Successful only if matches one key (V8.10 and above). |
|
MF_FILECLASS |
0x00400000 |
This is a file database type (V8.12 and above). |
|
MF_OPENBOGUS |
0x00800000 |
Open failed, don’t call map_close (V8.12 and above). |
|
MF_CLOSING |
0x01000000 |
This map is being closed (V8.12 and above). |
In addition to tracing map closures, the -d38.9 debugging switch
traces map appends allowed by the MF_APPEND flag
(-A on page 886) as specified
when the database is declared by the K configuration
command:
ndbm_map_store append=new db_map_store append=new
Here, new is the new value
appended to the old. Because this property is used
for alias files, the new and old values have a comma
inserted between them.
Trace NIS search for @:@ Debug command-line switch
The NIS alias map needs to contain an @:@ entry to indicate
that it is fully updated and ready for reading. But
because HP-UX omits the @:@, it is useful only as a check to
see whether the NIS map exists. The -d38.10 debugging switch
causes the result of this check to be printed
as:
nis_map_open: yp_match(@, domain, nisdb)Here, domain is the NIS domain, and nisdb is usually mail.aliases (but it can be redefined in your configuration file; see AliasFile on page 970). If the database map is not marked as optional (-o on page 889), the following error will be printed:
Cannot bind to map nisdb in domain domain: reason here
The -d38.10
debugging switch also traces the NIS+ open’s check
for a valid table:
nisplus_map_open: nisplusdb.domain is not a tableEssentially, this says that the NIS+ database map
nisplusdb (in the
domain shown) does not exist.
The error is printed even if the -o (optional) database
switch (-o on page 889) is
present.
Trace database map stores Debug command-line switch
The -d38.12
debugging switch shows values being stored in maps
that support updates:
db_map_store(name, key, value) ndbm_map_store(name, key, value) seq_map_store(name, key, value)
Here, the name is either the name
you gave to the database map with the K configuration command,
or a name assigned internally
by sendmail (such as
aliases.files). The
key is the key for the new
value that is being stored, and the
value is the value being
assigned to that key.
Trace switched map finds Debug command-line switch
A switched map is one that, either as the result of a service-switch file or because of sendmail’s internal logic, causes lookups to follow a select path. For example, Sun’s Solaris 2 nsswitch.conf might specify that aliases be looked up in the order files, then nis:
switch_map_open(name, file, mode) ← from -d38.2 switch_map_find => nummaps dbtype ...
First the number of database maps found is printed
with nummaps, and then the
database type for each map found in the list is
printed, such as files, or nis.
Trace database map lookups Debug command-line switch
The -d38.20
debugging switch traces many different map lookups.
The getcanonname( ) routine
looks up a hostname and tries to canonify it:
getcanonname(host), trying dbtype getcanonname(host), found getcanonname(host), failed, stat=error
Here, host is the hostname that
is being looked up, and dbtype
is one of files,
nis, nisplus, dns, or netinfo. If the
canonical name is not found, the
error shows one of the errors
listed in <sysexits.h>.
The process of canonifying the name is handled by
calling special subroutines based on the
dbtype:
text_getcanonname(host) ← dbtype is files nis_getcanonname(host) ← dbtype is nis nisplus_getcanonname(host), qbuf=query ← dbtype is nisplus dns_getcanonname(host, flag) ← dbtype is dns, printed with -d8.2 ni_getcanonname(host) ← dbtype is netinfo
The nisplus_getcanonname( )
routine is far more verbose than the other. In
addition to the preceding information, the -d38.20 switch also
prints:
nisplus_getcanonname(host), got count entries, all but first ignored nisplus_getcanonname(host), found in directory "nisdir" nisplus_getcanonname(host), found result nisplus_getcanonname(host), failed, status=nsistatus, nsw_stat=errno
The -d38.20
debugging switch also traces general lookups in
various kinds of databases. Again note that
nisplus is more verbose than
the others:
ndbm_map_lookup(name, key) db_map_lookup(name, key) nis_map_lookup(name, key) nisplus_map_lookup(name, key) qbuf=query nisplus_map_lookup(key), got count entries, additional entries ignored nisplus_map_lookup(key), found value nisplus_map_lookup(key), failed hes_map_lookup(name, key) ni_map_lookup(name, key) stab_lookup(name, key) impl_map_lookup(name, key) user_map_lookup(name, key) prog_map_lookup(name, key) prog_map_lookup(name): empty answer seq_map_lookup(name, key)
Here, the name is either the name
you gave to the database map with the K configuration command,
or one assigned internally by
sendmail (such as
aliases.files). The
key is the item being looked
up. The file is the pathname of
the file that contains the database.
Trace safefile( ) Debug command-line switch
The V8 sendmail program tries to
be extra careful about file permissions, and the key
to checking them is the internal
safefile( ) function. The
-d44.4
debugging switch[228] prints the parameters passed to the
safefile( ) function:
safefile(fname, uid=uid, gid=gid, flags=sff_flags, mode=wantmode)
Here, the file named fname is being checked to determine whether the user identified by the uid, with the group gid, is allowed to find or use the file. The range of checking is determined by the hexadecimal sff_flags, described in Table 15-11. Where a file’s permissions are required, the mode printed in wantmode will be used.
|
Mnemonic |
Hex flag |
Description |
|
SFF_ANYFILE |
0x00000000 |
No special restrictions |
|
SFF_MUSTOWN |
0x00000001 |
User must own this file |
|
SFF_NOSLINK |
0x00000002 |
File cannot be a symbolic link |
|
SFF_ROOTOK |
0x00000004 |
OK for root to own this file |
|
SFF_RUNASREALUID |
0x00000008 |
If no controlling user, run as real user-id |
|
SFF_NOPATHCHECK |
0x00000010 |
Don’t bother checking directory path |
|
SFF_SETUIDOK |
0x00000020 |
Set-user-id files are OK. |
|
SFF_CREAT |
0x00000040 |
OK to create file if necessary |
|
SFF_REGONLY |
0x00000080 |
Regular files only |
|
SFF_SAFEDIRPATH |
0x00000100 |
No writable directories (also check owner) |
|
SFF_NOHLINK |
0x00000200 |
File cannot have hard links |
|
SFF_NOWLINK |
0x00000400 |
Links only in nonwritable directories |
|
SFF_NOGWFILES |
0x00000800 |
Disallow group-writable files |
|
SFF_NOWWFILES |
0x00001000 |
Disallow world-writable files |
|
SFF_OPENASROOT |
0x00002000 |
Open as root instead of real user |
|
SFF_NOLOCK |
0x00004000 |
Don’t lock the file |
|
SFF_NOGRFILES |
0x00008000 |
Disallow group-readable files |
|
SFF_NOWRFILES |
0x00010000 |
Disallow world-readable files |
|
SFF_NOTEXCL |
0x00020000 |
Creates don’t need to be exclusive |
|
SFF_EXECOK |
0x00040000 |
Executable files are OK |
If both the SFF_NOPATHCHECK flag and the
SFF_SAFEDIRPATH flags are clear (are 0),
sendmail examines each
component of the path leading to the file. If any
component of the path is rejected, the -d44.4 debugging switch
causes sendmail to
print:
[dir fname] reason for the rejection here
A path component can fail because stat(2) failed. If the user-id is 0 for root, a warning is logged if a component is found to be group- or world-writable. For example:
hash map "Alias0": unsafe map file /etc/mail/aliases.db: World-writable directory
For each component in the path, safefile( ) checks to verify that this user has permission to search the directory. If the SFF_ROOTOK flag is not set (is clear), root (user-id 0) access is special-cased in that all directory components must be world-searchable.
Otherwise, the path component is accepted if it is
owned by the user-id and has
the user search bit set, or if its group is the same
as group-id and has the group
search bit set. If NO_GROUP_SET is undefined when
sendmail is compiled (NO_GROUP_SET on
page 130) and the DontInitGroups option (DontInitGroups on page 1023) is not
set, each group to which
user-id belongs is also
checked. Otherwise, the directory must be
world-searchable.
If the fname could not be checked
with stat(2), the -d44.4 debugging switch
causes the reason to be printed:
reason for failure hereIf the file does not exist, it might need to be
created. If so, sendmail checks
to be sure that the user-id has
write permission. The result is printed with the
-d44.4
debugging switch like this:
[final dir fname uid user-id mode wantmode ] error here
If the file exists and if symbolic links are
supported, the file is rejected if it is a symbolic
link and if the SFF_NOSLINK flag is set. If the
-d44.4
debugging switch is specified, this error is
printed:
[slink mode mode] EPERMIf the SFF_REGONLY flag is set, the file must be a
regular file. If it is not, it is rejected, and
-d44.4 causes
the following to be printed:
[non-reg mode mode] EPERMIf wantmode has the write bits
set, and the existing file has any execute bits set,
the file is rejected and -d44.4 causes the following to be
printed:
[exec bits mode] EPERMIf the file has more than one link, the file is
rejected and -d44.4 causes the following to be
printed:
[link count nlinks] EPERMIf the SFF_SETUIDOK flag is specified, if SUID_ROOT_FILES_OK (SUID_ROOT_FILES_OK on page 146) was defined when sendmail was compiled,[229] if the file exists, if it has the set-user-id bit set in the mode but no execute bits set in the mode, and if it is not owned by root, sendmail performs subsequent checks under the set-user-id and set-group-id identities of the existing file. A similar process occurs with the set-group-id bit. Sendmail then prints:
[uid new_uid, stat filemode, mode wantmode ]
If access is finally allowed, sendmail concludes with:
OK
Otherwise, it concludes with:
EACCES
Trace writable( ) Debug command-line switch
The -d44.5
debugging switch displays the values passed to
sendmail’s internal
writable( ) routine. This
routine nearly duplicates the function of the
access(3) call[230] but does it much more safely and allows
checks to be made under the identity of the
controlling user:
writable(fname, sff_flags)Here, the fname is the full
pathname of the file being checked. The
sff_flags are documented in
Table 15-11 earlier. Success or failure is described under
-d44.4.
Trace calls to the check_ rule sets Debug command-line switch
Beginning with V8.8, sendmail
calls rule sets whose names begin with check_ (The Local_check_ Rule Sets on page 252) to filter incoming and outgoing
mail, to accept or reject connections, and to decide
on actions, such as allowing STARTTSL. The -d48.2 debugging
switch[231] can be used to display the workspace
being passed to each such rule set:
rscheck(ruleset, left, right)The ruleset is the name of the named rule set being called. If right is missing, it prints as NULL, and the workspace passed to the rule set is:
leftIf right is present, the workspace is:
left $| rightHere, the $| in the
workspace is the $| operator.
Trace checkcompat( ) Debug command-line switch
The checkcompat( ) routine inside
conf.c can be tuned to solve
many problems (see Appendix C on
page 1248). The default -d49.1 (a.k.a. 49) debugging switch inside it prints
the arguments that were passed to it:
checkcompat(to=recipient, from=sender)
When designing your own
checkcompat( ), you should
only use the -d49
category to trace it.
Show disconnect from controlling TTY Debug command-line switch
When sendmail runs as a daemon, it must disconnect itself from the terminal device that is used to run it. This prevents keyboard signals from killing it and prevents it from hanging (on a dial-in line waiting for carrier detect, for example).
The -d52.1 (a.k.a.
-d52) debugging
switch shows sendmail
disconnecting from the controlling terminal
device:
disconnect: In fd Out fd, e=addr
For both its input and output connections, the
fd is a decimal
representation of the file descriptor number. The
addr is a hexadecimal
representation of the address that contains the
envelope information. If the LogLevel option (LogLevel on page 1040) is greater than
71, sendmail syslog(3)s the
following message to show that it has
disconnected:
in background, pid=pidHere, pid is the process identification number of the child process (the daemon).
Prevent disconnect from controlling TTY Debug command-line switch
The -d52.100
debugging switch prevents
sendmail from disconnecting
from its controlling terminal device. To show that
it is skipping the disconnect, it prints:
don't
This debugging switch is useful for debugging the
daemon. Note that this -d52.100 prevents the detach but allows
the daemon to fork(2). This
differs from the behavior of the -d99.100 debugging
switch (-d99.100 on page
574).
Trace database map lookups inside rewrite( ) Debug command-line switch
Rules defined by the R configuration command are rewritten
by sendmail’s internal
rewrite( ) subroutine. The
$[ and $( lookup operators
cause sendmail to look up keys
in database maps.
If sendmail is running in
deferred mode (DeliveryMode on
page 1004), it might skip some database map lookups
because they might take time to complete (as with
DNS, NIS, etc.). The -d60.1 (a.k.a. -d60) debugging switch causes
sendmail to print that it is
skipping the lookup:
map_lookup(dbtype, key) => DEFERREDHere, dbtype is the database map
type, such as dequote or host. The key is
the information being looked up.
If running in something other than deferred mode, sendmail performs the lookup. If the lookup fails (if key is not found), sendmail prints:
map_lookup(dbtype, key) => NOT FOUND (stat)
Here, stat is the number of the
error that caused the failure. If it is 0, the lookup failed
merely because the key was not
found. Otherwise, it corresponds to the error
numbers in <sysexits.h>.
Then, if stat is the special
value 75 (for EX_TEMPFAIL),
sendmail also prints:
map_lookup(dbtype, key) tempfail: errno=err
Here, err is the error number that corresponds to the errors listed in <errno.h>.
If the key is successfully found, sendmail prints:
map_lookup(dbtype, key) => replacement value here (stat)
Note that the replacement value will be whatever value
was defined by the -a database switch (-a on page 887) when the K configuration command
defined the database map.
Prevent backgrounding the daemon Debug command-line switch
The -d99.100
debugging switch[232] prevents the
sendmail daemon from forking
and putting itself into the background. This leaves
the running daemon connected to your terminal so
that you can see other debugging output. For
example:
# /usr/sbin/sendmail -bd -d99.100 -d9.30This allows you to watch the daemon perform RFC1413
identification queries when SMTP connections are
made. See also -d52.100, which prevents
sendmail from disconnecting
from its controlling terminal device, or the
-bD
command-line switch (-bD on page
233), which does both.
[225] * No -d4.1 (a.k.a. -d4) information is
available yet.
[226] * There is no
-d31.1
information.
[227] * There is no
-d35.1
information.
[228] * There is no
-d44.1
debugging information.
[229] * Note that set-user-id root files are permitted if sendmail was compiled with SUID_ROOT_FILES_OK defined, but we highly recommend against that definition.
[230] † It is more restrictive for root-owned files and can allow the set-user-id semantics needed for delivery to files.
[231] * There is no
-d48.1
information.
[232] * There is no
-d99.1
information available.