|
Chapter 33 Database Macros
|
|
Recall that the
K
configuration command (see
Section 33.3
)
is used like this:
K
name class args
The
class
determines the type of database that will be used.
For example, the class
btree
causes the Berkeley
db
(3) to be used,
whereas the class
dequote
causes an internal routine of
sendmail
's to be called.
In this section we present all the classes in alphabetical order.
They are summarized in
Table 33.3
of
Section 33.3.2
.
Most interaction with these classes can be watched by using the
-d38.2
debugging switch (see
Section 37.5.128
).
Some specialty maps use other debugging switches, which we indicate
where appropriate.
Berkeley's db form of database
(V8.1 and above)
The term btree stands for "balanced tree." It is a grow-only
form of database. Lookups and insertions are fast, but deletions
do not shrink the database. A good description of this form
of database can be found in
The Art of Computer Programming, Vol. 3: Sorting and Searching
,
D.E. Knuth, 1968, pp. 471-480.
The btree class is available only if
sendmail
was compiled
with
NEWDB
defined and the new Berkeley
db
library
linked in.
See
Table 33.5
in
Section 33.3.4
for a list of the
K
command switches that can be used with this
class and the meaning of each.
Look up the best MX record for a host
(V8.7 and above)
The
bestmx
map class looks up a hostname as the
key
and returns the current best MX record as the
value
.
Internally, a call is made to
getmxrr
() to get a list of
MX records for the host. That list is sorted in order
of the best to the worst, and
bestmx
returns the first.
Because
bestmx
is a class, not a map, you need to declare it with a
K
configuration
command before you can use it:
K
bestmx bestmx
One use for this class might be to see whether a particular host has
a usable MX at all:
Kbestmx bestmx
...
R$*< @ $+ > $* $: $1<@$2>$3 <$(bestmx $2 $: NO $)>
R$*< @ $+ > $* < NO > $#smtp $@ $2 $: $1 < @ $2 > $3
R$*< @ $+ > $* < $* > $: $1<@ $[ $2 $] > $3
In the first rule we look up the host part of an address (which has already
been focused by rule set 3) with the
bestmx
database map.
The result of the lookup is surrounded with angle brackets
and appended to the original address. The second rule looks for
the
NO
caused by an unsuccessful lookup (the
$:
).
The original address is then
sent with the
smtp
delivery agent. If the hostname
inside the appended angle braces is not
NO
,
the host part of the original address is canonicalized
with the
$[
and
$]
operators.
This
bestmx
class is a special internal one that can take
advantage of only two of the
K
command switches: the
-a
(as you saw) and the
-q
(to suppress dequoting the key).
This class can be watched with the
-d8
debugging switch
(see
Section 37.5.30, -d8.1
).
Really ndbm supplied with most versions of UNIX
(V8.1 and above)
The dbm class, which is really the
ndbm
form of database, is the
traditional form of UNIX database. Data are stored in one file, keys
in another. The data must fit in blocks of fixed sizes, so there is
usually a limit on the maximum size (1 kilobyte or so) on any given
stored datum. The
dbm
class is available only if
sendmail
was compiled with
NDBM
declared (see
Section 18.8.24, NDBM
).
This is the class of database traditionally used with alias files.
Because of the limit on the size of a datum, you should consider
using one of the
db
(3)
hash
or
btree
classes instead.
See
Table 33.5
in
Section 33.3.4
for a list of the
K
command switches that can be used with the
class and the meaning of each switch.
A pseudo map for removing quotation marks
(V8.6 and above)
V8
sendmail
can remove quotation marks from around
tokens by using the special
dequote
class. Because
dequote
is a class, not a map, you need to declare it with a
K
configuration
command before you can use it:
K
unquote dequote
This declares a map named
unquote
of the class
dequote
.
Once a map name has been declared, the
dequote
class can be
used in the RHS of rules to remove quotation marks. It is used
with
$(
and
$)
, just like database lookups:
$(unquote
tokens
$)
Here, arbitrary
tokens
are looked up in the database
named
unquote
. That database is special because it is
of the class
dequote
. Instead of really being looked up
in a
database,
tokens
will just have any surrounding quotation marks
removed:
"A.B.C"
becomes
A.B.C
"A"."B"."C"
becomes
A.B.C
"A B"
becomes
"A B"
"A,B"
becomes
"A,B"
"A>B"
becomes
"A>B"
The first example shows that surrounding quotation marks are removed.
The second shows that multiple quoted tokens are all de-quoted.
The last three show that
sendmail
refuses to dequote any tokens
that will form an illegal or ambiguous address when dequoted.
As an aid to understanding this dequoting process, run
the following two-line configuration file in rule-testing mode:
V7
Kdequote dequote
You can then use the
-bt
/map
command to try various
dequoting possibilities:
>
/map dequote "A.B.C"
map_lookup: dequote ("A.B.C") returns A.B.C (0)
>
/map dequote "A"."B"."C"
map_lookup: dequote ("A"."B"."C") returns A.B.C (0)
>
/map dequote "A B"
map_lookup: dequote ("A B") no match (0)
Note that beginning with V8.7, specifying the
-s
switch causes the space character to be replaced with another
character before dequoting (see
Section 33.3.4.10
).
V7
Kdequote dequote -s+
In that case the last example above would become the following:
>
/map dequote "A B"
map_lookup: dequote ("A B") returns A+B (0)
Also note that beginning with V8.8, specifying the
-a
switch causes a suffix of your choice to be appended to a successful
match:
V7
Kdequote dequote -a.yes
In that case the
"A.B.C"
example would become the following:
>
/map dequote "A.B.C"
map_lookup: dequote ("A.B.C") returns A.B.C.yes (0)
In addition to removing quotes, the
dequote
class also tokenizes
everything that is returned. It does this because quotes are ordinarily
used to mask the separation characters that delimit tokens.
For example, consider the
$&
operator. It prevents a macro in a rule from being expanded
when the configuration file is read and always returns a single
token, no matter how many tokens it really contains. Consider this
configuration file:
V7
DXhost.domain
Kdequote dequote
R$* $: $&X , $(dequote "" $&X $)
Here, the macro
X
is assigned
host.domain
as its value.
The only rule in the file (when
sendmail
is run in rule-testing mode)
prints the expression
$&X
to show that it is a single
token, then prints the result of dequoting that same expression.
Note that an empty token needs to be dequoted. Putting quotes around
$&X
itself won't work. The output produced by rule-testing mode
looks like this:
> 0 foo
rewrite: ruleset 0 input: foo
rewrite: ruleset 0 returns: host.domain , host . domain
>
$X
$X dequoted
No debugging switch is available to watch the actions of the
dequote
class.
Berkeley's db form of database
(V8.1 and above)
The
hash
class uses a hashing algorithm for storing
data. This approach to a database is described in
A New Hash Package for UNIX
, by Margo Seltzer (USENIX
Proceedings, Winter 1991). The hash class is available only if
sendmail
was compiled with
NEWDB
defined and the new
Berkeley
db
library linked in.
The
hash
class is the default that is used with most of the
FEATURES offered by the
m4
technique (see
Table 33.6
in
Section 33.6, "Database Maps and m4"
). For example, consider the
following:
Kuudomain hash -o /etc/uudomain
Here, a map named
uudomain
is declared to be of class
hash
.
The
-o
says that the file
/etc/uudomain
is optional.
See
Table 33.5
in
Section 33.3.4
for a list of the
K
command switches that can be used with this
class and the meaning of each.
MIT network user authentication services
(V8.7 and above)
The
hesiod
class of map uses the Hesiod system,
a network information system developed as Project Athena.
Support of
hesiod
maps is available only if you declare
HESIOD when compiling
sendmail
. (See
Section 18.8.10, HESIOD
for a fuller description of the Hesiod system.)
A
hesiod
map is declared like this:
K
name
hesiod
HesiodNameType
The
HesiodNameType
must be one that is known at your site, such
as
passwd
or
service
.
An unknown
HesiodNameType
will yield this error when
sendmail
begins to run:
cannot initialize Hesiod map (
hesiod error number
)
One example of a lookup might look like this:
Kuid2name hesiod uid
R$+ $: $(uid2name $1 $)
Here, we declare the map
uid2name
using the Hesiod-type
uid
, which converts
uid
numbers into login names. If the
conversion was successful, we use the login name returned; otherwise, we
use the original workspace.
See
Table 33.5
in
Section 33.3.4
for a list of the
K
command switches that can be used with this
class and the meaning of each.
Internal table used to store and look up hostnames
(V8.1 and above)
The
host
class is a special internal database used
by
sendmail
to help it resolve hostnames. It is fully
described under the
$[
and
$]
operators in
Section 33.4.3
.
The
-d9
debugging switch (see
Section 37.5.37, -d9.1
)
can be used to watch the actions caused by this
host
class.
Search for an aliases database file
(V8.1 and above)
The
implicit
class refers specifically to
aliases
(5)
files only. It causes
sendmail
to first try to open a
db
(3) hash-style alias file, and if that fails or if
NEWDB support was not compiled in, it tries to open a
ndbm
(3)-style database.
If that fails,
sendmail
reads the
aliases
(5) source file
into its internal symbol table.
Although you can declare and use this class in a configuration file,
there is no reason to do so. It is of use only to the internals of
sendmail
. If
implicit
fails to open an
aliases
file (probably because of a faulty
AliasFile
(
A
) option;
see
Section 34.8.1
),
sendmail
will issue the following
error if it is running in verbose mode:
WARNING: cannot open alias database
bad file name
If the source
aliases
file exists but no database form
exists,
sendmail
will read that source file into its
internal symbol table using the
stab
class (see
Section 33.8.16
).
The Lightweight Directory Access Protocol
(V8.8 and above)
LDAP stands for
L
ightweight
D
irectory
A
ccess
P
rotocol and provides access to the X.500 directory.
The
ldapx
class is used to look up items in
that directory service. It is declared like this:
K
name
ldapx
switches
Lookups via LDAP are entirely defined by the switches specified.
To illustrate, consider the following X.500 entry:
cn=Full Name, o=Organization, c=US
sn=Name
uid=yourname
cn=Full Name
commonname=Full Name
mail=yourname@mailhub.your.domain
objectclass=person
objectclass=deptperson
To look up a login name in this database and have the official
email address for that user returned, you might use a declaration like this:
Kldap ldapx -k"uid=%s" -v"mail" -hldap_host -b"o=Organization, c=US"
Note that the
-k
switch is in the form of a
ldap_search
(3)
filter, where the
key
will replace the
%s
and then the
whole expression will be searched for as the
key
. The
-b
is required to specify the base from which to search. Note that
a base must be selected such that it ensures that
sendmail
will
always get a unique result.
The following rule can be used with the above declaration to look
up the preferred mail address for a user:
R$* <@ $+ > $* $: $(ldap $1 $: $1<@$2>$3 $)
Here we presume that this rule was preceded by a call to rule set 3
to focus on the host part. If the lookup succeeds, the new (unfocused)
address is returned from the
mail=
line in the database. Otherwise,
the original address is returned.
A few errors can occur during
sendmail
's startup that indicate a
faulty
K
command:
LDAP map: -h flag is required
LDAP map: -b flag is required
No return attribute in
map name
The first two show that those switches are mandatory. The third prints
only to show that the
-v
switch is mandatory if the
-o
switch is absent.
In addition, each successful lookup can cause a line like the following to
be logged via
syslog
(3):
qid
: ldap
key
=>
value
See
Table 33.5
in
Section 33.3.4
for a list of the
K
command switches that can be used with this
class and the meaning of each. Also,
Table 33.6
lists
several nonstandard switches that are used by this
ldapx
class.
Finally, note that the
ldapx
class can be used only if LDAPMAP
was defined when
sendmail
was compiled (see
Section 18.8.15, LDAPMAP
).
NeXT Computer's network information services
(V8.7 and above)
NetInfo is NeXT's implementation of a network-based information service.
The
netinfo
class expects a map declaration to be
of the following form:
K
name
netinfo
map
Other switches may be used with this class, and they
have their normal meanings (see
Table 33.5
in
Section 33.3.4
).
Support of
netinfo
maps is available only if you declare
NETINFO when compiling
sendmail
(see
Section 18.8.27, NETINFO
).
Sun's Network Information Services (NIS)
(V8.6 and above)
Sun Microsystems offers a network information service
called NIS. It provides the ability to look up various kinds
of information in network databases. The
nis
class allows you
to access that network information by way of rules in rule sets.
You declare an
nis
class map like this:
K
name
nis
map
Here,
name
is the identifier that you will later use in rule sets.
The
map
is any
nis
map. Lookups will occur in the
default
nis
domain. If you wish to specify some other domain,
you may append an
@
character and the domain name to the
map
:
K
name
nis
map
@
domain
To illustrate, consider the need to look up the name of the central
mail server for your department. If such a map were called
mailservers
,
you could use the following configuration file line to look up
your domain in that map:
Kmailservers nis -o mailservers
...
R$* <@ $+ > $* $: $1<@$2>$3 <$(mailservers $2 $)>
R$* <@ $+ > $* <$+> $#smtp $@ $4 $: $1 < @ $2 > $3
...
Here, we look up the host part of an address (
$2
) in the
mailservers
nis
map.
The
-o
makes the existence of the map optional.
If the host part is found, it is rewritten to be the name of the mail
server for that host. In the last rule we forward the original
address to that server.
Without the
-o
, the nonexistence of a map will cause this
error to be logged:
Cannot bind to map
name
in domain
domain
:
reason here
If
nis
is not running at all or if
sendmail
cannot bind
to the
domain
specified or the default domain, the following
error is logged:
NIS map
name
specified, but NIS not running
The
nis
class is available only if
sendmail
is compiled with
NIS defined (see
Section 18.8.29, NIS
).
See
Table 33.5
in
Section 33.3.4
for a list of the
K
command switches that can be used with this
class and the meaning of each.
Sun's newer version of NIS
(V8.7 and above)
Sun Microsystems's NIS+ is a complete redo of its earlier
nis
system. The
nisplus
class allows you to look up
information using NIS+. The form of that class declaration looks like
this:
K
name
nisplus
map.domain
Here, the
map
is a NIS+ map name, such as
mail_aliases
.
[7]
If the
domain
or
.domain
is missing, the
nisplus
default
domain is used. If the entire
map.domain
is missing, the default
becomes
mail_aliases.org_dir
. The domain
org_dir
contains
all the systemwide administration tables.
Any lookup failures that can be retried will automatically be retried up to
five times, with a
sleep
(3) of 2 seconds between each try.
If the
map.domain
doesn't exist in the local
nisplus
system, this error is printed when
sendmail
starts:
Cannot find table
map
.
domain
:
reason for failure here
This error is suppressed if the original
K
command declaration included
the
-o
switch.
Two other errors can happen during startup:
map
.
domain
:
reason for failure here
is not a table
nisplus_map_open(
map
): can not find key column
-k column name here
You can use the
-k
switch to specify a
key
column to look up.
Under
nisplus
, columns are named, so the
-k
must be followed by
a valid name, or the last error above will be printed. You can also use
the
-v
switch to specify the
value
column, also a name. If
the
-v
is omitted, the last column becomes the default.
See
Table 33.5
in
Section 33.3.4
for a list of the other
K
command switches that can be used with this
class and the meaning of each.
Provide a never found service
(V8.7 and above)
The
null
class is an internal database that always returns
a failed lookup. It is useful for replacing other classes to force
failures without errors. Normally, the
null
class is used
internally only.
Consider a tiny configuration file that does not need the use
of the
aliases
facilities. One way to declare aliases
would be like this:
O AliasFile=null:
This tells
sendmail
to use the
null
class for looking
up aliases. Therefore no aliases will ever be found.
None of the
K
command switches may be used with the
null
class. If you try to use any, they will be silently ignored.
No debugging switch is available to watch this
null
class.
Run an external program to look up the key
(V8.7 and above)
The
program
class allows you to perform lookups via arbitrary
external programs. The form for the declaration of this class looks
like this:
K
name
program
/path arg1 arg2 ...
The
/path
must be the full pathname to the program.
Relative paths will not work, and attempts to use them
will log the following error
and cause the lookup to fail:
NOQUEUE: SYSERR(bcx):
relative name
: cannot exec: No such file or directory
The program is run under the
uid
and
gid
of the person who ran
sendmail
.
But if that person is
root
, the program is instead run as the user and group
specified by the
DefaultUser
(
u
) option (see
Section 34.8.15, DefaultUser (g)(u)
).
The arguments to the program always have the key to be looked up added as a final
argument:
K
name
program
/path arg1 arg2 ...
key added here
This is the only way that the key can be passed to the program. The key
will specifically not be piped to the program's standard input.
The value (result of the lookup) is read from the program's standard output.
Only the first MAXLINE-1 characters are read (where MAXLINE is
defined in
conf.h
, currently as 2048). The read result is processed
as an address and placed into the workspace (unless the
-m
switch
is used with the
K
command).
To illustrate, consider the need to look up a user's preferred address
in an external relational database:
Kilook program /usr/lib/ingres_lookup -d users.database
This program has been custom written to accept the key as its final argument.
To prevent spurious errors, it exits with a zero value whether the key
is found or not. Any system errors cause it to exit with a value selected from
those defined in
<sysexits.h>
(those recognized by
sendmail
).
Error messages are printed to the standard error output, and the found
value (if there was one) is printed to the standard output.
In general, it is better to use one of the database formats known to
sendmail
than to attempt to look up keys via external
programs. The process of
fork
(2)ing and
exec
(2)ing the
program can become expensive if it is done often, slowing down the
handling of mail.
See
Table 33.5
in
Section 33.3.4
for a list of the
K
command switches that can be used with this
class and the meaning of each.
Search a series of maps
(V8.7 and above)
The
sequence
class is a more general form of the
implicit
class described for use with alias files. The
sequence
class
allows you to declare a single name that will be used to search a
series of databases. It is declared like this:
K
name
sequence
map1 map2 ...
Here, a
key
will be looked up first in the map named
map1
, and
if not found there, it will be looked up in the map named
map2
. The class of
each of the listed maps should logically relate but need not be the same.
Consider, for example, a rule's LHS that will match
if the workspace contains either a user's login name or the name of a host,
with the hostname taking precedence:
Khosts host -a+ /etc/hosts
Kpasswd user -a- /etc/passwd
Kboth sequence hosts passwd
R$- $: $(both $1 $)
Here, we say that the map named
both
is of type
sequence
.
Any single token in the LHS will be looked up first in the
map named
hosts
, and if it is found there the hostname will be
returned with a
+
appended. If it is not found in the
hosts
map, it will be next looked up in the
passwd
map. If it is found there, the original workspace will be returned
with a
-
appended. If the workspace is not found in either
map, the lookup fails and the workspace remains unchanged.
If any map in the series of maps declared with the
K
command does
not exist:
Kboth sequence hosts passwd badname
the following error is printed, and that map is ignored:
Sequence map
both
: unknown member map
badname
If the number of maps that are sequenced exceeds the maximum allowed
(MAXMAPSTACK in
conf.h
, currently 12), the following
error is printed, and the overflow of maps is ignored:
Sequence map
name
: too many member maps (
max
max)
None of the
K
command switch may be used with the
sequence
class. If you try to use any, they will be wrongly interpreted as
map names.
Internally load aliases into the symbol table
(V8.6 and above)
The
stab
class is used internally by
sendmail
to
load the raw
aliases
(5) file into its internal symbol table.
[8]
This is a fallback position that is taken if no database form of aliasing
is found.
The
stab
class should
never
be used in configuration
files.
Built sequences based on service switch
(V8.7 and above)
The
switch
class is used internally by
sendmail
to create
sequence
classes of maps based on external service-switch
files. Recall that the lines inside a service-switch file look like this:
service how how
as, for example:
aliases files nis
This line tells
sendmail
to search for its aliases first in
files then in NIS.
To illustrate the
switch
class, consider the need to look up
aliases inside rule sets in the same way that
sendmail
looks up
its own aliases.
To do this, you would declare a
switch
map, as, for example:
Kali switch aliases
This causes
sendmail
to search for the
service
named
aliases
in the service-switch file.
In this example it finds such a line, so
for each
how
that follows the
aliases
in that line,
sendmail
creates a new map with the name
ali
followed by a dot
and the
how
:
[9]
aliases files
becomes
ali.files
aliases nis
becomes
ali.nis
These named maps are then sequenced for you.
Recall that
sequence
maps are declared like this:
K
name
sequence
map1 map2,...
The
name
given to the sequence is
ali
. In our
example the following sequence is automatically created for you
from your original
switch
declaration:
Kali sequence ali.files ali.nis
In rule sets, when you look up aliases with the
ali
map:
R... $( ali $1 $)
the sequence named ali
you will use the
sequence
named
ali
that was automatically
built for you from a combination of your original
switch
definition
and your service-switch file's
aliases
line.
That is, you declare a
switch
, but you use a
sequence
.
Look up in flat text files
(V8.7 and above)
The
text
class allows you to look up keys in flat text files.
This technique is vastly less efficient than looking up keys in
real databases, but it can serve as a way to test rules before
implementing them in database form.
For the
text
map, columns for the key and value are both
measured as an index. That is, the first column is number 0.
To illustrate, consider the following miniconfiguration file
that can be used to check spelling:
Kspell text /usr/dict/words
Spell
R$- $: $( spell $1 $: not in dictionary $)
The
/usr/dict/words
file contains only a single column of words.
The above rule shows that the key is (by default) the first column (index 0).
And the value is (by default) also the first column (index 0).
For more sophisticated applications you can specify the key's column
(with the
-k
switch) the value's column (with the
-v
switch) and the column delimiter (with the
-z
switch).
To illustrate, consider the need to look up a
uid
in the
/etc/passwd
file and to return the login name of the user to
whom it belongs:
Kgetuid text -k2 -v0 -z: /etc/passwd
R$- $: $( getuid $1 $)
The lines of a password file look like this:
ftp:*:1092:255:File Transfer Protocol Program:/u/ftp:/bin/sh
The third column (where the columns are separated by colons) is
the
uid
field. The first is the login name. Note that
the
-k
and
-v
switches show these fields as
indexes, where the first is 0 and the third is 2.
See
Table 33.5
in
Section 33.3.4
for a list of the
K
command switches that can be used with this
class and the meaning of each.
No debugging switch is available to watch this
text
class.
Look up in the User Database
(V8.7 and above)
The
userdb
class allows you to look things up in the User
Database (see
Section 33.5, "The User Database"
for a full description of
the User Database). The
userdb
class is declared with the
K
command like this:
K
name
userdb
switches
keyword
V8.7 and above
Here, the
keyword
is the name of the field to search and is either
maildrop
or
mailname
(see
Section 33.5
).
There is no need to list any files or servers with this command. Those should
already have been declared with the
UserDatabaseSpec
(
U
) option
(see
Section 34.8.75
).
One possible use for a
userdb
map might be to
check for a local account in the
check_rcpt
rule set
(see \#sRULESETS_check_rcpt).
In this example, all valid incoming recipient addresses are listed with
the User Database:
Kislocal userdb maildrop
Scheck_rcpt
R$* $: $>3 $1 focus on host
R$* <@ $+ > $* $: $1 discard host
R$+ $: $(islocal $1 $: nope $)
Rnope $#error $@ 5.1.3 $: "Recipient is not local"
See
Table 33.5
in
Section 33.3.4
for a list of the
K
command switches that can be used with this
class and the meaning of each.
The
-d28
debugging switch (see
Section 37.5.97, -d28.1
) can be used
to watch this
userdb
class in action.
Look up local passwd information
(V8.7 and above)
The
user
class is used to look up
passwd
(5) information using
getpwent
(3). A password entry typically looks like this:
ftp:*:1092:255:File Transfer Protocol Program:/u/ftp:/bin/sh
Here, there are seven fields, each separated from the others by colon
characters. The key is always compared to the first field. The value
returned is (by default) the first field unless you specify another
field with a
-v
switch:
K
name
user -v
field
Here,
field
can be either a number 1 through 7 or one of the names
name
,
passwd
,
uid
,
gid
,
gecos
,
dir
, or
shell
, which correspond to the numbers.
For example, to look up usernames and get the full name (
gecos
) field
returned, you could use something like this:
Kgetgecos user -vgecos
...
R$- $: $( getgecos $1 $)
Note that this returns the full
gecos
field in its rawest form.
It is not cleaned up to provide a reliable full name, as is the
$x
macro (see
Section 31.10.42, $x
).
One possible application for the
user
class is in conjunction with
the
check_rcpt
rule set (see \#sRULESETS_check_rcpt).
In the following we check to see whether a recipient is a local user
and reject the mail if that is not so:
Kislocal user
Scheck_rcpt
R$* $: $>3 $1 focus on host
R$* <@ $+ > $* $: $1 discard host
R$- $: $(islocal $1 $: nope $)
Rnope $#error $@ 5.1.3 $: "Recipient is not local"
Here, we focus on the host part with rule set 3, then discard all
but the user part in the second rule. The third rule performs
the lookup. If the user is found, that username is returned unchanged.
If, on the other hand, the user is not found, the token
nope
is
returned. The last rule rejects any SMTP RCPT command
that contains a nonlocal user part.
See
Table 33.5
in
Section 33.3.4
for a list of the
K
command switches that can be used with this
class and the meaning of each.
|