Sendmail is one of those applications that can do just about anything (as long as you know the secret handshake that gets you access to detailed information about it’s configuration).
I’ve been using it for about 1 year to allow my company’s website to send email to our users. To avoid all the headaches involved in making sure our emails don’t get rejected as spam, we use googlemail as a smart host since they host our email accounts for our domain.
This has been working great, but recently we ran into a limitation that would be a deal breaker if it couldn’t be solved.
The Problem:
- When using googlemail as your smart host, you must use authentication and Google rewrites the from address of all your emails to the user’s email address that you use to authenticate. Thus, if you authenticate with webmaster@example.com’s credentials, all email from your server will seem to come from webmaster@example.com. Even if you specify a different sender!
- When sendmail is configured to use a smart host that requires authentication (like googlemail), it chooses the authentication credentials based on the host name or IP address of the smart host. So, unless you use multiple smart hosts, sendmail will only use 1 set of authentication credentials when connecting to the smart host.
- We are now hosting 2 websites on the same server with completely different domain names that each need to send email from different addresses that belong to their respective domains.
When you combine all three parts, the problem becomes clear:
How do I send email from info@yyy.com when sendmail will always use info@zzz.com’s credentials for smart host authentication, thus making Google rewrite the from address so that all email from my server appears to come from info@zzz.com?
The Solution:
To me, the best solution would be for sendmail to choose smart host authentication credentials based on the sender address of each email.
For example:
- Sendmail receives an email message to deliver from info@yyy.com
- Instead of looking up “smtp.googlemail.com” in authinfo, it looks up “info@yyy.com”
Seems simple enough, but, after hours of searching the web, I found that sendmail is just plain not configured to do this.
However, everything it needs to be able to do this is already available, it just doesn’t use it. So I decided to make sendmail use it by editing the sendmail.cf file.
I know, I know, I’m supposed to use sendmail.mc, but darn it all if I wasn’t able to get this to work using the macro file.
So, without further ado, here’s what I did to make sendmail behave the way I wanted it to.
The How To:
Assumptions:
I’m assuming that you already have sendmail configured to use a smart host that requires authentication. It is beyond the scope of this document to cover that.
Instructions:
1) Edit the authinfo section of sendmail.cf so that it looks like this:
######################################
### authinfo: lookup authinfo in the access map
###
### Parameters:
### $0: {f}
### $1: {server_name}
### $2: {server_addr}
######################################
Sauthinfo
R$* $: <$(authinfo AuthInfo:$&{f} $: ? $)>
R<?> $: <$(authinfo AuthInfo:$&{server_name} $: ? $)>
R<?> $: <$(authinfo AuthInfo:$&{server_addr} $: ? $)>
R<?> $: <$(authinfo AuthInfo: $: ? $)>
R<?> $@ no no authinfo available
R<$*> $# $1
The key here is the $&{f} macro. In sendmail, it stands for the sender’s address from the envelope of the email.
The above code tells sendmail to look for entries in the authinfo file that match the sender’s email address. If no match is found, then check for entries that match the smart host’s name/IP.
In effect, this preserves sendmail’s original behavior as the fall back if no match is found in the authinfo file for the sender’s address.
2) Add sender credentials to the authinfo file (its location is defined by the authinfo feature in sendmail.mc):
AuthInfo:info@ex.com “U:info@ex.com” “P:xx” “M:PLAIN”
AuthInfo:info@yyy.com “U:info@yyy.com” “P:xx” “M:PLAIN”
AuthInfo:info@zzz.com “U:info@zzz.com” “P:xx” “M:PLAIN”
AuthInfo:smtp.sh.com “U:info@ex.com” “P:xx” “M:PLAIN”
AuthInfo: “U:info@ex.com” “P:xx” “M:PLAIN”
In the example above, the first 3 entries are credentials for different senders that use the server to send email (they take advantage of the changes we made in step 1). The last 2 entries are the original smart host authentication configuration which ensures that sendmail will still be able to connect to the smart host and send the email using a default set of credentials, even if the sender’s address does not match any of the other entries.
3) Remake the authinfo database using the “makemap” command.
4) Make sure to comment out any lines in your init script for sendmail that recompile sendmail.cf using the sendmail.mc script. The location of this file on Redhat variants is: /etc/init.d/sendmail
(if you don’t do this, your changes to sendmail.cf will be lost when you restart sendmail!)
5) Restart sendmail.
You should now be able to control which user’s credentials are used to authenticate with the smart host on a case by case basis by changing the sender’s address on the email.
This is specified using the -f flag when calling sendmail on the command line (like PHP’s mail() function does).
Final Thoughts:
While this gets the job done, it would be nice to be able to incorporate the changes in step 1 into the sendmail.mc file. This would make it much easier to maintain since anyone who runs the “make” command on the /etc/mail directory will destroy the changes we made to sendmail.cf in step 1.

You need to edit /usr/share/sendmail-cf/m4/proto.m4, if you want your changes to be preserved when you run “m4 sendmail.mc”. Just search the file for “AuthInfo” and you will find the right section quickly.
On a final note: thank you a thousand times! This blog was exactly what I was looking for! You saved my skin!
@quirks: Thanks for the tip on editing the proto.m4 file. I’m glad my humble little blog was helpful to you.
This is much easier done by using the smarttable file to configue what sender addresses should be handled by which smarthosts.
http://web.archive.org/web/20071021005904/http://anfi.homeunix.net/sendmail/smarttab.html
Usage
In smarttable file you can put entries like the ones given below:
test@mike.com.hk lesspopular.mailhub.com
@mike.com.hk popular.mailhub.com
test@domain.pl uucp:nodex
test@domain.us esmtp:[smtp.domain.us]:my.isp
# relay for sender [version 8.2+ of smarttable]
@ relay:smtp.myisp.com
lesspopular.mailhub.com will be used to relay messages send from test@mike.com.hk. Messages from remaining addresses in mike.com.hk will be relayed via popular.mailhub.com. You can also specify mailer used as shown in the remaning lines.
The lastest smarttable version is 8.5 released 2002-07-28. I detected problems in versions 8.1-8.4
Install
1.
Create /etc/mail/smarttable file and compile it using makemap.
2.
Copy provided smarttable.m4 file into cf/feature directory.
Use “Save as” command in your browser. In some cases “copy and paste” looses required info (e.g. tabs – \t)
3.
In *.mc file you use to generate sendmail.cf add:
FEATURE(`smarttable’)dnl
and generate new sendmail.cf or sendmail-test.cf.
Tests
You can use commands given below for testing the feature:
sendmail -C sendmail-test.cf -bt <<END
3,0 recipient@test.com
.Dfsender@sender.domain
3,0 recipient@test.com
END
Additional
* smarttable uses sender addresses befere masquerading (e.g. genericstable rewrite).
* smarttable is not consulted for deliveries to addresses in local domains
* mailertable is consulted before smarttable
* DO NOT use feature/smarttable.m4 pre 8.5 releases
o versions 8.2-8.3 were newaliases unfriendly
o versions 8.1-8.4 routed local address with no domain part via smarttable
* Another solution for sender based smart host selection has been proposed by Neil Ricket. HACK(`sender_based_routing') is available at http://www.cs.niu.edu/~rickert/cf/
* Example of smarttable usage is given at http://lena.franken.de/linux/mail_sendmail_etc.html#sendmail_from_based_routing
Original Posting
googleThe posting
Subject: Re: How to relay the mail according to the sender domain
Date: 1999-02-05
Newsgroups: comp.mail.sendmail
Message-ID:
@geohump: Thanks for the tip on smarttable. That looks like a very useful addition to sendmail.
However, it does not solve the problem I was writing about in the article. My issue was that we only had one smart host and needed to authenticate with different email addresses. Not route outgoing emails to different smart hosts.
Thanks cthayer
This blog was exactly what I was looking for. It solved my problem.
Hello,
We are using google apps business edition. I have configured sendmail to relay emails of our google apps account but what I want to configure is, if user john having email address “john@domain.com” sends email to any user, it should get saved in the sent folder of the mailbox of the user john at google apps and so on for other users also. Is it possible to achieve this?
@Dhanil: If you authenticate with Google as user “john” to do the relay, then Google should save the message in the user’s sent history. This post is all about how to authenticate with Google as different users based on the sending email address. Also, check out the comment above by quirks.