Using SendMail as an MDA

Support for E-Mail addresses

Make sure that the domain is supported, as described in the section about supported domains.

Mail delivery methods may include the following. (These are listed in no special order; there may be an order typically used, but if so, then it is not documented here at this time.)

Local mailbox

In order for this method to work for a user, SendMail requires that the user has a local account on the computer (that is running SendMail). More details about this method may be covered in the section about mailboxes.

forward file

OpenBSD manual page for .forward files describes a mechanism where an end user can change forwarding information simply by editing a file that the end user has access permissions to be able to adjust.

[#sndmadom]: Supporting additional domains
Adjusting virtual-domains or local-host-names

Details on this are discussed by the section on sendmail” command's supported domains.)

[#sndmvusr]: virtuser

Having separate namespaces can be nice, because that allows a single username (such as adam@) to be used on multiple domains (such as example.com and sitetwo.zz) and for E-Mails to those addresses to go to different locations. So, for example, E-Mail sent to adam@example.com would go to a different E-Mail box than adam@sitetwo.com, and possibly may even get forwarded to a different remote E-Mail server).

To accept mail on different domains, and allowing the individual domains to have their own separate namespaces like what was just described, the recommended way to set this up is to use the virtusertable.

Using virtuser is a bit more complex than using E-Mail aliases. However, it also gives some more flexibility than the method of using SendMail's aliases file. First, if a single mail server serves multiple domains, then the virtuser method allows a username to be visible at one domain, while not being a user that exists on another domain. (This is not something that would be so easily supported by just using the aliases file.) Second, using this virtuser method does not have any requirement to make a local user account on the E-Mail server.

So, this method does permit some more flexibility. There is, however, a bit more to the setup process. (Expect this method to take a bit of time to implement.)

Configuring so that the domain may receive E-Mail

This is basically a revision of the section about sendmail” command's supported domains. (This section is more specific to preferred methods when supporting virtuser.)

The commentary about certain domains being unnecessary to specify, which is commentary found in the section about sendmail” command's supported domains, remains valid. (So, do not put the system's host names in either file.)

For additional domain names, probably the best thing to do (perhaps for no other reason than that this seems to make the most sense) is to include a name in the /etc/mail/local-host-names file only if the domain name is a name for the E-Mail server (or at least a domain that the E-Mail server is in). If the E-Mail server is providing mail services for remote networks, those names of the remote networks can go into the /etc/mail/virtual-domains file. Do not fear the commentary, by the section on sendmail” command's supported domains, about /etc/mail/virtual-domains being unsupported by the default configuration file. If using the virtuser approach, a customized configuration may be needed anyway (in order to support the /etc/mail/virtusertable file), so configuration file customziation is going to be getting needed.

[#sndmvtdm]: Adding support for the /etc/mail/virtual-domains file
Having a configuration file with the needed contents

First, it will probably make some good sense to back up the existing /usr/share/sendmail/*.cf files (which probably consists of the three files sendmail.cf and localhost.cf and submit.cf). If the cpytobak program is being used:

cpytobak /etc/mail/*.cf /usr/share/sendmail/cf/*.mc | more

Choose the first one of the following methods. (At some point, the second option may gain some further details.)

Creating a new file
Modifying a configuration “source” file to add support

We will modify the file that has been used to create the /etc/mail/sendmail.cf file. For example, in OpenBSD, the OpenBSD's manual page for “afterboot” says the /etc/mail/sendmail.cf “file was generated from openbsd-proto.mc.” Clearly, that filename is probably OpenBSD-specific, so other operating systems will likely have that /etc/mail/sendmail.cf file being created from a different /usr/share/sendmail/cf/*.cf file. See: checking which *.mc file to work on. If using OpenBSD, the file being modified will (for this example) be the file with openbsd-proto.mc as a filename.

Since the Makefile has references to support a file named openbsd-proto.mc, fewer changes are needed if a file with that filename gets modified. So, first back up a copy of that file, and then edit that file.

cd /usr/share/sendmail/cf/
sudo mkdir ./backup
sudo cp openbsd-proto.mc ./backup/openbsd-proto-origver.mc
echo $VISUAL
sudo $VISUAL openbsd-proto.mc

Find some lines in the text file. (Referencing the virtusertable filename may be a useful search term.)

dnl Enable support for /etc/mail/virtusertable.
dnl Used to do N -> N address mapping.
FEATURE(`virtusertable', `hash -o /etc/mail/virtusertable')dnl
dnl Rewrite (unqualified) outgoing email addresses using the
dnl mapping listed in /etc/mail/genericstable
FEATURE(genericstable, `hash -o /etc/mail/virtusertable')dnl

Insert a line, after the sentence about Rewrite (and before the next line of code). The line should look like this:


... and so the portion of the text file may look something like this (after being edited). (The text file is shown in three parts to make it easier to notice where the line got inserted.)

dnl Enable support for /etc/mail/virtusertable.
dnl Used to do N -> N address mapping.
FEATURE(`virtusertable', `hash -o /etc/mail/virtusertable')dnl
dnl Rewrite (unqualified) outgoing email addresses using the
dnl mapping listed in /etc/mail/genericstable
FEATURE(genericstable, `hash -o /etc/mail/virtusertable')dnl

Save the change to the file.

Method involving creating a new file

At the moment, this has not been thoroughly tested by the author, and is written out of speculation. It looks like there may be a superior way to handle this: On OpenBSD, the ${CFDIR}/cf/openbsd-localhost.cf file is very short and simply includes another file. Additional support for the “localhost” configuration file might be provided by the file named “${CFDIR}/cf/Makefile

Creating a required file

If sendmail configuration states that the /etc/mail/virtual-domains is usable, then that becomes a required file. The file is not optional: it must exist (even if the file is an empty, zero byte file).

sudo touch /etc/mail/virtual-domains
Updating the configuration file that SendMail will be using

(If manually typing, the part before the first make may be skipped if the shell is already using that as the current/present working directory. Although the command may be optional, it should not fail if it is attempted.)

export CFDIR=/usr/share/sendmail
ls -ld ${CFDIR}

That directory should exist. If not, presumably the directory might exist in a different location. (Whoever created the particular SendMail distribution, which might be whoever created the operating system distribution, may have chosen to have files be placed in a different location.) Some research or file hunting may be needed. (This might help: “ sudo find / -iname "*cf.m4" ”. Ignore the m4/ subdirectory.)

Once ${CFDIR} is pointing to the right location, run:

cd ${CFDIR}/cf && sudo make && sudo make distribution
echo Err=$?
sudo mailq

The middle command should say “Err=0

Handling problems

This should not be needed if there did not appear to be any problems.

If there are problems, perhaps try:

m4 ${CFDIR}/m4/cf.m4 filename.mc | sudo -n tee /etc/mail/sendmail.cf

(The previous example command line(s) have been based on examples provided by the instructions for how to use a *.mc file and properly create an updated *.cf file.)

Once the file does seem to be updated, verify that the output file did get the desired updates:

grep -i "F{VirtHost}/etc/mail/virtual-domains" /etc/mail/sendmail.cf
echo Err=$?

That last grep command will output the specified text if that text is found in the file. If the command actually outputs the contents between the quotation marks, then the output of the next command should have stated Err=0, and these things indicate that the configuration file update appears to have been successful.

If everything worked well, go ahead and restart SendMail. (Note that the current command line shown with ps may have been mutilated since the command line that was used to start SendMail. Perhaps see stopping SendMail and running Sendmail.)

Using support for the virtusertable
[#sndmvtbc]: Contents of the virtusertable file

Edit the virtusertable “configuration file”:

The contents of the configuration file will depend on how mail should be handled. Domain names may be customized, special support for individual E-Mail addresses may be added, and so different organizations will likely have some very different configurations. For organizations with extremely simple configurations, leaving the configuration file completely blank might actually be a perfectly fine option. (If the “virtusertable” file does not indicate how E-Mail should be handled, then the MTA software may just try some other mail-handling methods like using E-Mail aliases or local mailboxes.)

An example file


userone@example.org someone@example.com
usertwo@example.org %1@example.net

Any E-Mail sent to userone@example.org will be delivered to the someone@example.com E-Mail address.

Any E-Mail sent to usertwo@example.org will be delivered to the usertwo@example.net E-Mail address. (The username is unchanged, so hopefully the username @example.net does match the username that is used at the @example.org site.)

Understanding the configuration file
cpytobak /etc/mail/virtusertable
echo $VISUAL
sudo $VISUAL /etc/mail/virtusertable

MicroBSD Handbook: Sendmail (archived at the Wayback Machine @ Archive.org) says "This file is processed in a first match order down the file." In a shown example, documentation says that a third line doesn't execute when an earlier line does.

The virtusertable file says:

# See the "virtusertable" section of /usr/share/sendmail/README for
# more information.

Sendmail.cf/README features page (which is the same essential text as the /usr/share/sendmail/README file) gives example of some commands that can be used, including:

info@foo.com foo-info
info@foo.com bar-info
joe@bar.com error:nouser 550 No such user here
jax@bar.com error:5.7.0:550 Address invalid
@baz.org jane@example.net

These configuration lines are discussed further in the official documentation file that contains the example configuration lines.

[#sndmmkvd]: Apply changes to the /etc/mail/virtusertable.db file

Back up files.

cpytobak /etc/mail/virtusertable.db /etc/mail/virtusertable

The main point to that is to make a quickly accessible back up of the /etc/mail/virtusertable.db file (which is the “database” variation of the /etc/mail/virtusertable file).

The online repository showing OpenBSD's virtusertable file says to rebuild the database by running a command as root. The command in that file can be shown by running:

grep -i "makemap" /etc/mail/virtusertable

The following command may be a bit more verbose, and do the needed job:

cpytobak /etc/mail/virtusertable
sudo makemap -v hash /etc/mail/virtusertable < /etc/mail/virtusertable

Note: The filespec shown after “hash is actually only showing part of the filename that will be output. In this example, a /etc/mail/virtusertable.db is what actually gets output.

Then restart SendMail (or give it a SIGHUP?) and then use:

sudo sendmail -bv user@example.org.

If that works well, then try using a real SMTP session. Either do this manually, using the SMTP sample documentation as needed, or run:

(Other E-Mail addresses my also be tried.)

If it says “User unknown” for a user that is on an internal domain, make sure that the full domain is provided, and that the domain ends with a period. Also make sure that the makemap command (as shown in the earlier example) has been run after the last change has been made. Also restart the software.

Note: A note was made here that relaying was denied. Perhaps there is an error in the documentation. This may need to be reviewed...
E-Mail aliases

This is covered in the section about forwarding/relaying E-Mail.