Fun with changing E-Mail Addresses
Published Jan 10 2005 12:14 PM 44.2K Views

One may think that making changes to the e-mail address of a mailbox is a simple thing, but Exchange does a bit of work to ensure the changes are correct and will not cause problems in the system.
 
Here's an overview of how the UI updates e-mail addresses and how it validates and checks for uniqueness when changes are made.

E-Mail Address Attributes

Exchange stores and uses information about the e-mail addresses of a recipient in the following attributes:

   proxyAddresses 

This is the main attribute where e-mail address information is kept. When you open the properties of a recipient in Outlook and look at the "E-mail Addresses" tab, you are looking at this attribute. This is a multi-valued string containing all the addresses that represent the recipient. Each value must have the following format:

      type:address

For example:

      SMTP:nospam@online.microsoft.com

When the type is in uppercase letters, the address is considered to be the primary address of that type and it is used as the default reply address of that recipient. When the type is in lowercase letters, the address is considered a secondary address and is used to resolve addresses during e-mail delivery, allowing the same recipient to receive e-mails directed to different e-mail addresses.

For example: 
         Primary:      SMTP:currentAlias@domain.com
         Secondary:  smtp:oldAlias@domain.com

On the 'Users and Computers' snap-in, this property is edited on the 'E-mail Addresses' page of a recipient.

   targetAddress

In contacts and mail-enabled users this attribute contains the type and address of the mailbox represented by the recipient. This will point to a mailbox outside the Exchange organization, for example, to a hotmail account or to another's company address.
 
On the 'Users and Computers' snap-in, this property is edited on the 'Exchange General' page of contacts and mail-enabled users.

   mail

The value of this attribute corresponds to the primary SMTP proxy address. Windows often displays this attribute as the e-mail address of the user.
 
On the 'Users and Computers' snap-in, this property is edited on the 'General' page of recipients.

   textEncodedOrAddress

The value of this attribute corresponds to the primary X400 proxy address.
 
On the 'Users and Computers' snap-in, this property is edited by changing the primary X400 address on the 'E-mail Addresses' page of recipients.

It is important to note that the values found in mail, textEncodedOrAddress and targetAddress must also be included in proxyAddresses with their respective types, otherwise they would not be picked up when Exchange makes searches against proxyAddresses.
 
However, this creates a problem: we actually need to keep these attributes synchronized to each other when the administrator makes changes to them, either in the UI or with CDOEXM. The problem is aggravated because in 'Users and Computers' Windows implements the property page that sets the mail attribute, while the Exchange extension implements the property pages with targetAddress and proxyAddresses. Not only do we need to synchronize changes when the property page is saved but we need to synchronize when the administrator flips from one page to the other, to keep the UI consistent. To do that, we run what we call the proxy-sync mechanism.

Proxy-Sync Scenarios

Proxy-Sync runs when an administrator makes a change in one of the e-mail attributes of a recipient and that change needs to be synchronized to another attribute. For example, when mail changes, the primary SMTP entry in proxyAddresses must also be updated so that both addresses are synchronized, but if you try to delete the mail attribute without mail-disabling the recipient, then we copy the primary SMTP address back to mail.

The following list summarizes the changes supported by proxy-sync since Exchange 2000 SP2:

1.    Action: Remove e-mail from General page.
Results: Primary SMTP from proxyAddresses is copied back to mail.

2.    Action: Modify e-mail on General page.
Results: There are four cases to be considered:

o        If the new address already exists in proxyAddresses and:

·         it is the primary SMTP address: proxy is in sync already.

·         it is a secondary SMTP address: demote the curr ent primary SMTP and promote the new address to primary SMTP.

o        If the new address does not already exists in proxyAddresses and:

·         targetAddress is the primary SMTP: demote the current primary SMTP and add the new address as primary SMTP.

·         targetAddress is a secondary SMTP: replace the primary SMTP with the new address.

3.    Action: Modify the primary SMTP on E-mail Addresses page, either by editing or by promoting a secondary address to primary.
Results: new primary SMTP is copied to mail.

4.    Action: Modify the primary X400 on E-mail Addresses page, either by editing or by promoting a secondary address to primary.
Results: new primary X400 is copied to textEncodedOrAddress.

5.    Action: Modify the address corresponding to targetAddress in the E-mail Addresses page.
Results: The new address is copied to targetAddress.  Actions 3 and 4 also apply if the edited address is a primary proxy.

6.    Action: Modify the targetAddress in the Exchange General page of contacts and mail-enabled users.
Results: The following rules are applied:

o        If the old targetAddress is the primary SMTP and the new targetAddress:

·         is also SMTP: remove the old primary SMTP.

·         is not SMTP: keep the primary SMTP intact.

·         In either case, continue following the next rules:

o        If there is already a primary address for the same type, add the targetAddress as a secondary address.

o        If there is not a primary address for the same type, add the targetAddress as a primary address and if it is SMTP or X400, copy to mail or textEncodedOrAddress, respectively.

E-mail Address Validation

Well, now that all our e-mail addresses are synchronized, we can try to save them, right? No, we are not quite there yet. Before saving we must make sure that all addresses are valid, according to their type.

 

When validating the proxyAddresses attribute, we'll check the following:

o        There must be a primary SMTP address

o        There can be only one primary address of each type

o        Every secondary address type must have a corresponding primary address

o        All addresses must pass validation of their type

·         This is actually done by the proxy generation DLL associated with each type. I won't go in details on that here since you can find more information about them in MSDN.

·         Now, these DLLs will not be installed in an admin-only installation, so we need to RPC to an Exchange server and let the server perform that validation. The Exchange System Attendant service responds by calling each proxy DLL and letting them validate the e-mail addresses typed by the user.

Can we save now? Close, but not yet. There is still one step left.

Uniqueness Check

We would not like to let an administrator accidentally create duplicate e-mail address when we can prevent that from happening. I mean, if that happens messages would start returning, people will complain and everybody gets frustrated. So let's do this one last thing before saving changes to the e-mail addresses of a recipient: let's make sure they are all unique in the organization.

 

To do that, we perform an LDAP query against the Global Catalog, looking for any object that has any of the proposed values in its proxyAddresses attribute. The query will look somewhat like this, with as many clauses as e-mail addresses we need to check: (| (proxyAddresses=SMTP:alias@domain.com) (proxyAddresses=smtp:alias2@domain.com) )

 

Of course, we need to properly format and escape the e-mail addresses in the query but most importantly, we need to be aware of the fact that there may be one object with the same addresses that we're trying to save, which would be the object we are editing. That one is ok, but if anyone else shows up in that query, we have a duplicate and we do not allow the changes to be persisted.

 

What about Recipient Policies?

 

You may be wondering why I haven't mentioned Recipient Policies anywhere. The process described above happens in the user interface, completely independent of Recipient Policies. It goes without saying that once the recipient is updated, Recipient Policies will go make sure everything is according to policy, but that's another story.

 

- Fabio Pintos

9 Comments
Not applicable
Interesting post. I'm wondering, have you noticed this bug regarding the uniqueness check and contacts: <br> <br>* Create a mail-enabled user <br>* Create a mail-enabled contact with an external address. <br>* (wait for the RUS to process) <br>* Open the contact and change the 'mail' value from the 'general' tab to equal the primary address of the user in the previous step. <br>* OK out of the property sheet. <br> <br>DSA will alert you of the conflict, but if you open up the object again (or view it from LDAP), the conflicting change has indeed been written.
Not applicable
How would you explain this: <br>If I do an LDIFDE import with these fields, when I see user properties all the proxy addresses are set as default and appear bold. <br>Should I use &quot;SMTP&quot; in lower case? I haven't tried that yet. <br> <br>dn: cn=dlist01,ou=adc_import,dc=company,dc=com <br>changetype: add <br>objectClass: group <br>mailNickName: dlist01 <br>displayName: DL Fica 01 <br>proxyAddresses: SMTP:dlist01@company.com <br>proxyAddresses: SMTP:dlistsec@company.com <br>proxyAddresses: SMTP:dlistter@company.com <br>proxyAddresses: groupType: 8 <br>instanceType: 4
Not applicable
I've seen situations where changing the email address on the general tab causes the ADC to create custome recipients. Is this due to the proxy-sync scenario?
Not applicable
Is there a reason why the Exchange General tab is not exposed in ADModify.Net? If it was then we would be able to modify the targetAddress attribute for contacts and mail-enabled users. I think this would be a great addition to the tool.
Not applicable
After reading this article it seems that you can change the “targetAddress” from 'Users and Computers' snap-in to any email address (like a hotmail account) but you can only select an AD object (at least with Exch2k) <br>I thought I could put any address in that field in order to provide an easy “.forward” feature to the users through a web page. If I put a foreign address (like @Hotmail) through ADSIEdit or any other tool in the “targetAddress” field, the forwarding doesn’t work. <br>I have to do it with targetAddress -&gt;Contact AD object with foreign address. That’s the way MS says in some KB article, but it’s more troublesome and involves an administrative action. <br>Did I did anything wrong when I tried using “targetAddress” in this way? Is there any easier way to allow the users to set up their own “forwards”? <br>Thank You <br> <br>J Crespo
Not applicable
Can you think of any reason why moving a mailbox enabled user would cause the following:

Existing Primary SMTP Address demoted to secondary and new Primary SMTP generated (appended with number to maker unique) ie

before move:

Primary SMTP: Joe.Bloggs@MyDomain.com
Secondary smtp: none

After move:
Joe.Bloggs2@MyDomain.Com
Secondary smtp: Joe.Bloggs@MyDomain.com
Not applicable
But the Uniqueness Check works not if you change the eMail-Address over the General Tab (mail attribute), so editing here is useless.
Not applicable
Hi,

The process of moving a mailbox will not change its e-mail addresses. What comes to my mind is the possibility that the move is causing the mailbox to belong to a different recipient policy or something like that and the Recipient Update Service decided to update the e-mail addresses of the mailbox.

One suggestion is to set RUS to never run, do the move, inspect the mailbox to check its state, compare it to the policies and then let RUS run again and confirm if that is what is touching the e-mail address.
Not applicable
When you add an SMTP Address to an existing user account, Exchange (and we are talking Exchange 2003...
Version history
Last update:
‎Jul 01 2019 03:03 PM
Updated by: