Click here to Skip to main content
Click here to Skip to main content

Exchange Domain Mail SMTP Sink

, 1 Nov 2006
Rate this:
Please Sign up or sign in to vote.
How to create a domain mail sink for Exchange Server.

Active Directory Users and Computers - notice


A while ago, I started running Microsoft Small Business Server with Microsoft Exchange 2003. I use Outlook with RPC over HTTP, synchronize with Exchange on my Smart Phone, and use OWA. I also host a few domains on my server.

When I signup for a service, I want to give as my e-mail address, so that I can block spam. It’s easy to add SMTP addresses to Active Directory accounts, but I have accounts on a thousand services! Hence the following question: how do I get * routed in Exchange?

If you just want to install this sink, download the binaries and run RegisterSink.cmd. Add to users that should receive all e-mail Run UnregisterSink to uninstall.


These two articles are an excellent start, but I have more than one domain and I want this to be configurable.

What does this code do?

  • Implement IMailTransportSubmission::OnMessageSubmission to catch submitted e-mail messages.
  • Search for an Active Directory user that has an exactly matching mail or proxy address.
  • Search for an Active Directory user that has a matching mail or proxy address.
  • Route e-mail accordingly.
  • Log routing events to the event log.

Implementation Details

Please note that the samples below are stripped of error checking. Please see the actual source code attached.

First, I had to follow the details in Writing Managed Sinks for SMTP and Transport Events and create the managed proxy objects to receive SMTP events.

Code to connect to Active Directory code is widely available. The slightly tricky parts are connecting to the RootDSE and finding the Users node.

// Root DSE and the Users LDAP path
mRootDSE = new DirectoryEntry(
 "LDAP://" + (DomainName.Length > 0 ? DomainName + "/" : string.Empty) +
mUsersLDAPPath = "LDAP://" + 
 (DomainName.Length > 0 ? DomainName + "/" : string.Empty) + 
 "CN=Users," + RootDSE.Properties["defaultNamingContext"].Value;

When an e-mail arrives, it will be potentially re-routed. A new list of recipients must be created.

void IMailTransportSubmission.OnMessageSubmission(
 MailMsg message,
 IMailTransportNotify notify,
 IntPtr context)
 Message Msg = new Message(message);
 RecipsAdd NewRecipients = Msg.AllocNewList();
 bool fReRouted = false;
 foreach (Recip Recipient in Msg.Recips)
     fReRouted |= ReRoute(Recipient, Msg, NewRecipients);
 if (fReRouted)

And the meat of the re-routing:

private bool ReRoute(Recip Recipient, Message Msg, 
                     RecipsAdd NewRecipients)
     ActiveDirectory Directory = new ActiveDirectory();
     string[] SearcherPropertiesToLoad = { "cn", "mail", 
                                     "proxyAddresses" };
     DirectorySearcher Searcher = new DirectorySearcher(
      new DirectoryEntry(Directory.UsersLDAPPath),
      (proxyAddresses=*smtp:@" + 
      Recipient.SMTPAddressDomain.ToLower() + 
      "*)(proxyAddresses=*smtp:" + 
      Recipient.SMTPAddress + "*)))",
     SearchResultCollection SearchResults = Searcher.FindAll();
     if (SearchResults.Count == 0) return false;
     foreach (SearchResult SearchResult in SearchResults)
      foreach (string ProxyAddressProperty in 
       string ProxyAddress = ProxyAddressProperty.ToLower();
       if ("smtp:" + Recipient.SMTPAddress.ToLower() == 
        // there's an address that matches
        // exactly, add him to the re-routing
        // list because there might be other
        // recipients that don't match and
        // will require routing
               Recipient.SMTPAddress, null);
        return false;
     foreach (SearchResult SearchResult in SearchResults)
      foreach (string ProxyAddressProperty in 
       string ProxyAddress = ProxyAddressProperty.ToLower();
       // this is necessary to avoid matching
       // with
       if ("smtp:@" + Recipient.SMTPAddressDomain.ToLower() == 
        string RoutedSMTPAddress = 
        NewRecipients.AddSMTPRecipient(RoutedSMTPAddress, null);
        return true;
     return false;

That's it. This was overall a simple task, and should, frankly, ship with Microsoft Exchange. This code can probably be easily extended to support regular expressions and other fancy things.


  • 10/24/2006: initial release.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Team Leader Application Security Inc.,
United States United States
Daniel Doubrovkine has been in software engineering for twelve years and is currently development manager at Application Security Inc. in New York City. He has been involved in many software ventures, including Xo3 and Vestris Inc, was a development lead at Microsoft Corp. in Redmond, and director of Engineering at Visible Path Corp. in New York City. Daniel also builds and runs a foodie website,

Comments and Discussions

GeneralMy vote of 5 PinprofessionalAmir Mohammad Nasrollahi7-Aug-13 23:12 
QuestionCreate domains is the same? PinmemberFelipe.Gonzalez20-Nov-07 14:25 
AnswerRe: Create domains is the same? PinmemberdB.21-Nov-07 3:30 
This is very unrelated to the Exchange sink. You need to do some reading on Active Directory.

Question?!?!?!?! PinmemberHillai9-May-07 3:06 
AnswerRe: ?!?!?!?! PinmemberdB.9-May-07 3:30 
QuestionNewRecipients? PinmemberPletzky7-Nov-06 21:07 
AnswerRe: NewRecipients? PinmemberdB.8-Nov-06 3:13 
GeneralRe: NewRecipients? PinmemberPletzky8-Nov-06 7:03 
Generalbest solution Pinmembermikedepetris6-Nov-06 23:56 
GeneralRe: best solution PinmemberdB.7-Nov-06 3:59 
GeneralRe: best solution Pinmembermeraydin4-Sep-07 11:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150224.1 | Last Updated 1 Nov 2006
Article Copyright 2006 by dB.
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid