Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  1. The AD Daily Updater, a Java program driven by the Oracle ACS1 database, which populated a select set of "biographical" fields (firstname, lastname, job title) in the AD for non-private people. None of these fields were are important from a system point of view, except for UPN which is an identifier to login to services.The Mail Relay configuration, which maps Yale Email Aliases (where all the mail ends in "@yale.edu") to a "native" Email system suffix that distinguishes the specific mail system for that account  (ending in "@connect.yale.edu" for O365 or "@bulldogs.yale.edu" for Eliapps). , but AD information is displayed in the Outlook mail client.
  2. A separate function embedded in the AD Daily Updater Java jar file that enforces a standard set of Exchange mail routing fields in AD (MailNickName and ProxyAddresses). This is a subset of the Mail Relay data currently affecting only O365 mail accounts, but while the Mail Relays answer the question "What Mailbox does this Mail Alias point to", the Exchange Mail Routing is provisioned with the equivalent reverse answer "What Aliases are delivered to this Mailbox".

The new code To accomplish this

  1. This project will provision the same biographical fields

...

  1. with the same data, only it will source this data from the

...

  1. new IDR instead of the

...

  1. old Oracle ACS1 database.

...

We have to plan ahead for expected changes that do not currently have a schedule:

  • The on premise Exchange system exists only to support system tools that use it. The old AD Updater depended on it and is one of the things that had to change before we could decomission something that performs no real business service.
  • The Mail Relay machines will at some point be decommissioned and the Exchanged Online function in the Azure Cloud will take over routing all mail addressed to an "@yale.edu" Alias. Since Exchange Online is configured by Azure AD in essentially the same way that on premise Exchange was configured by on premise AD, we have to add ProxyAddresses to some AD object (User or Contact) for Email Aliases that point to Eliapps (and a few legacy departmental servers).
  • The Email Alias system is currently one table (SMART.DIR_ONLINE_INFO) and a Package of code in the SMART schema of the Oracle ACS1 database. At some time this function may move to a SQL Server so we can eliminate our Oracle license costs.

The Mail Relays translate any given "@yale.edu" Email address to some system specific address. They are even handed and treat O365 and Eliapps equally. Exchange Online, however, is mostly a system to deliver mail to its own mail accounts, although it will forward mail to Eliapps or other external mail systems, but only in the event that it cannot be delivered to any internal O365 mailbox. When a user has both O365 and Eliapps accounts, the "bias" that Exchange Online has toward O365 will result in some mail being delivered to the O365 Inbox that the Mail Relays would previously have been delivered to Eliapps. There is a structural feature of the Microsoft system and we cannot work around it. Other than this limitation, we design the new code so that every piece of mail will be delivered by the new system to the same location where the old system sent it.

There are a set of Yale and Exchange rules. We can't change the Microsoft rules, and we are not prepared to change Yale rules established long ago. Enumerating the rules explains exactly how and why certain mail routing will change.

  • It is an AD rule that every User must have a unique UserPrincipalName. The UPN can be used to login to Windows and must be used to login to Azure.
  • It is a Yale rule that for Users with a mail account, the Primary Email Alias (first.last@yale.edu) is also the UserPrincipalName. The ALIAS_NAME (before the "@") is the MailNickName (first.last). For Users marked Private the ALIAS_NAME is the Netid, and for old accounts after the date where they are supposed to be deleted, the ALIAS_NAME is also set to Netid to free the first.last for new people who happen to have the same name.
  • It is an Exchange Online rule that for Users with an O365 mail account, the UPN has to be a deliverable Email address to that account. With Mail Relays, the UPN can point to either O365 or Eliapps, but if Exchange Online does all the mail routing, any mail addressed to the Primary Email Alias (which is also the UPN) will go to O365 if there is an O365 mailbox even though the Email Alias table points the Primary Email Alias to an Eliapps account.
  • It is an Exchange Online rule that the same Email address cannot be in two ProxyAddress lists of two Azure AD objects. So if we create a Contact object for the Eliapps account, we cannot add the Primary Email Alias to it, and if that is the only alias that points to the account, we cannot meaningfully create the Contact in the first place.

Yale policy is to give users either O365 or Eliapps mail but not both, but exceptions are allowed. Yale policy is that when a user has both O365 and Eliapps mail, the O365 account is Primary. So if we followed our own rules there would be no problem. Unfortunately, either because accounts were "grandfathered" in from previous systems or because someone important asked for an exception, there are about 5 cases where the Primary Email Alias points to Eliapps and there is a secondary alias pointing to an existing O365 account. We will have to remediate these users.

This is not an AD Updater problem. It is a Mail System restriction that we cannot program around and will be ignored by the coding. We will do what we can do. There are ways to change the Email Aliases with Dependent Netids that can work around the problem, but that again is an Email System trick and not part of this project. However, understanding how mail delivery is done and how it changes is important to understanding the design, and this particular glitch is a useful example to motivate a description of the environment to which this code must be designed.

The big design feature that derives from this explanation, is that when the Alias table is read in by IIQ (is "aggregated" in IIQ terms) it is presented as one of four different configurations of object data by a database view that coverts the flat raw table into a usable set of database "rows" (which become program objects):

  1. Unchanged User object - Netids with Primary O365 accounts and no Eliapps account (most employees, including faculty). All the Aliases to the O365 account are grouped and presented as an object keyed by the MAILBOX ("Netid@connect.yale.edu"). By extracting the Netid from the MAILBOX name, IIQ correlates this to an Identity and therefore an AD User object. All the ALIAS_NAMES for that MAILBOX become ProxyAddresses. This should produce the exact same result (except for the order of the aliases in the list) as the current AD Daily Updater, so we expect no change to the AD for this type of account.
  2. User object with Eliapps routing - Netids with a Primary Eliapps account and no O365 Mail (although non-mail O365 licenses). Adopting the exact same logic as the previous case, except that the MAILBOX is now (AliasName@bulldogs.yale.edu), this populates the ProxyAddresses list with aliases to the Eliapps account, and sets the TargetAddress to the MAILBOX value. Initially this does nothing, but when the Mail Relays are decommissioned, it routes Eliapps mail to Google. Because Netid is not in the MAILBOX, the Netid field in the Alias Table has to be used to find the right Identity to which this data should be attached.
  3. Unchanged User object and Contact with Eliapps Routing - Users with a Primary O365 account and a Secondary Eliapps account. The O365 alias data will generate the same data as in Case 1 above. The Eliapps aliases will generate a second row with the Case 2 data, but because it is a secondary Email account, IIQ has to create a second Contact object in AD to hold the Eliapps data since the User object is busy holding the O365 data.
  4. Routing "Junk" Contact objects - Entries in the Email Alias table that were not processed to generate a ProxyAddress in one of the previous three steps are grouped by unique MAILBOX value. Each MAILBOX value creates a "junk" Contact whose ProxyAddresses are the list of ALIAS_NAMEs that had that MAILBOX value. Note that this method of collection may combine Aliases owned by different Netids if they point to the same MAILBOX, but this is OK.

There is a fifth category of unprocessed aliases. Any Alias with a MAILBOX of "xxxx@connect.yale.edu" where the prefix xxxx is not a Netid must be a resource (a room, distribution list, etc.) and will not be processed. Exchange Online knows these things and handles them natively, so we don't have to create objects to inform Exchange about its own native stuff.

Any user can have Junk, so while each mail user Netid is either Case 1, 2, or 3, they can also have any number of Type 4 entries. Type 4 is grouped by MAILBOX and correlated to a Contact identified by the MAILBOX. It is not connected in any way to the Netid that owns the Alias. The junk aliases are spread across mailman, elilists, panlists, cs, som, aya, invest, med, physics, chem, geology, cmp, math, astro (all .yale.edu). Some of this is obsolete, but cleaning it up is future scope.

Users with an O365 or Eliapps account can delete it, and users with one type of account can get the other. So you can transition between Type 1 and 3, or 2 and 3. This is a delicate process because IIQ cannot directly move a field like ProxyAddresses from a User object to a Contact object in a single transaction (as would be possible with database SQL). This is, however, a manual process and becomes a function of the Mail System people. This code does not provide transition services but will provide documentation about how to make the transition correctly

Once you understand the four possible "packages" of mail routing data, the mechanism for gathering the data and passing it to IIQ is relatively simple. A SQL query of the Alias table (DIR_ONLINE_INFO) groups rows by MAILBOX. The AliasNames of the same MAILBOX are concatenated together in a string field. If the MAILBOX is "@connect.yale.edu" it is O365, if it is "@bulldogs.yale.edu" it is Eliapps, and if it is something else it is junk. The trick is then to create SQL clauses that flag primary accounts from secondary accounts, and distinguish Eliapps account that exist alone from Eliapps accounts belonging to someone who also has an O365 mailbox which have to be then assigned to a Contact. If we don't do this processing in SQL where it is easy, it becomes much more difficult in IIQ to know if an incoming Eliapps account record belongs to a Netid who also has an O365 record and therefore correlate it to or create a Contact Identity. If the SQL view has already done that analysis, IIQ can implement the correlation that the SQL has pre-processed.

...

  1. We use this opportunity to alter certain business practices, such as excluding certain fields for SOM users from central administration.
  2. This project will also create the same mail routing fields for current O365 users in the Local AD, although the current code was originally designed for On Premise Exchange and certain obsolete features will not be duplicated.

The purpose of this code is to provision fields in the Azure AD. That is where Outlook goes to look for O365 accounts and directories. That is where Exchange Online goes to deliver mail to mailboxes or forward mail to Eliapps. However, because we run a Local AD and an Azure AD synchronized to each other, the current AD Daily Updater and this replacement code populate data only in the Local AD and the expect it to be copied thorough the Azure AD Connector synchronization tool within the next half hour.  Except for an additional feature added to this new code (to directly change the UserPrincipalName in Azure AD if it is incorrect), the specification of this project is to change the Local AD and except for enumerated differences, to put the same data in Local AD that the existing Java code put there. There is no need for an Azure AD to develop the code or test correct function. 

When this project goes live, it will begin to provide features that the old AD Updater did not have, in preparation for changes that are anticipated but do not currently have a target date.

  • We currently have an On Premise Exchange system that serves no business purpose, but exists to not disturb incidental behavior required by various tools, including the old AD Updater. For example, the old Updater did not believe you were an Exchange user unless the msExchVersion field in the Local AD was set to a non-null value. That field was populated by On Premise Exchange when it creates a "RemoteMailbox". This project will not look at that field in AD, but believes that you are an O365 user if you have an Email Alias to an O365 account.
  • The old AD Updater created Mail Routing fields in AD only for Exchange mail users. The new code creates the same fields for Exchange mail users, but also creates the same fields in other User or Contact objects for Eliapps users. This new data will be required when the Mail Relay system is retired.
  • The "Email Alias System" refers to database logic in the Oracle ACS1 table, but in the future we may move this to SQL Server, so the new code will minimize dependencies on Oracle specific features.

The Email Alias and Mail Relay system implements a "goes to" methodology looking up email addresses and selecting a target mail system for that address. Every Alias has a row in the table, and aliases to the same Inbox are represented by multiple rows with the same destination MAILBOX value. The Exchange Online system depends on AD maintaining a "comes from" list, where the AD User object associated with the Inbox has a list of email addresses that get delivered to the mailbox.

For example the current system is based on a table that says:

"john.doe@yale.edu" goes to the mail account for AD User jd234
"jack.doe@yale.edu" goes to the mail account for AD User jd234
"jane.doe@yale.edu" goes to the mail account for AD User jd235

While the Exchange model is:

The AD User object jd234 has a list with "john.doe@yale.edu" and "jack.doe@yale.edu" as names for the mail account.
The AD User object jd235 has a list with just "jane.doe@yale.edu".

This is an over simplification because Exchange also forces us to add several built in required email names on top of the email address published for each user, but the important concept is that the Mail Relay and Exchange models express the same information from two opposite directions. This would not be a problem, except that over time the rules have not been followed and the data in the tables is not clean.

There is also a compatibility issue because the Mail Relays treat O365 and Eliapps equally, while Exchange will deliver mail to the O365 Inbox if at all possible. When information about the Email Aliases is ambiguous, the is mail that the Mail Relays will reliably send to Eliapps but that Exchange will instead send to O365 for a user who has both types of accounts. This is not, however, an issue for the AD Updater replacement project but will have to be addressed later on with the follow on "Mail Relay replacement" project. 

There are a set of Yale and Exchange rules. We can't change the Microsoft rules, and we are not prepared to change Yale rules established long ago. Enumerating the rules explains exactly how and why certain mail routing will change.

  • It is an AD rule that every User must have a unique UserPrincipalName. The UPN can be used to login to Windows and must be used to login to Azure.
  • It is a Yale rule that for Users with a mail account, the Primary Email Alias (first.last@yale.edu) is also the UserPrincipalName. The ALIAS_NAME (before the "@") is the MailNickName (first.last). For Users marked Private the ALIAS_NAME is the Netid, and for old accounts after the date where they are supposed to be deleted, the ALIAS_NAME is also set to Netid to free the first.last for new people who happen to have the same name.
  • It is an Exchange Online rule that for Users with an O365 mail account, the UPN has to be a deliverable Email address to that account. With Mail Relays, the UPN can point to either O365 or Eliapps, but if Exchange Online does all the mail routing, any mail addressed to the Primary Email Alias (which is also the UPN) will go to O365 if there is an O365 mailbox even though the Email Alias table points the Primary Email Alias to an Eliapps account.
  • It is an Exchange Online rule that the same Email address cannot be in two ProxyAddress lists of two Azure AD objects. So if we create a Contact object for the Eliapps account, we cannot add the Primary Email Alias to it, and if that is the only alias that points to the account, we cannot meaningfully create the Contact in the first place.

Yale policy is to give users either O365 or Eliapps mail but not both, but exceptions are allowed. Yale policy is that when a user has both O365 and Eliapps mail, the O365 account is Primary. So if we followed our own rules there would be no problem. Unfortunately, either because accounts were "grandfathered" in from previous systems or because someone important asked for an exception, there are about 5 cases where the Primary Email Alias points to Eliapps and there is a secondary alias pointing to an existing O365 account. We will have to remediate these users.

This is not an AD Updater problem. It is a Mail System restriction that we cannot program around and will be ignored by the coding. We will do what we can do. There are ways to change the Email Aliases with Dependent Netids that can work around the problem, but that again is an Email System trick and not part of this project. However, understanding how mail delivery is done and how it changes is important to understanding the design, and this particular glitch is a useful example to motivate a description of the environment to which this code must be designed.

The big design feature that derives from this explanation, is that when the Alias table is read in by IIQ (is "aggregated" in IIQ terms) it is presented as one of four different configurations of object data by a database view that coverts the flat raw table into a usable set of database "rows" (which become program objects):

  1. Unchanged User object - Netids with Primary O365 accounts and no Eliapps account (most employees, including faculty). All the Aliases to the O365 account are grouped and presented as an object keyed by the MAILBOX ("Netid@connect.yale.edu"). By extracting the Netid from the MAILBOX name, IIQ correlates this to an Identity and therefore an AD User object. All the ALIAS_NAMES for that MAILBOX become ProxyAddresses. This should produce the exact same result (except for the order of the aliases in the list) as the current AD Daily Updater, so we expect no change to the AD for this type of account.
  2. User object with Eliapps routing - Netids with a Primary Eliapps account and no O365 Mail (although non-mail O365 licenses). Adopting the exact same logic as the previous case, except that the MAILBOX is now (AliasName@bulldogs.yale.edu), this populates the ProxyAddresses list with aliases to the Eliapps account, and sets the TargetAddress to the MAILBOX value. Initially this does nothing, but when the Mail Relays are decommissioned, it routes Eliapps mail to Google. Because Netid is not in the MAILBOX, the Netid field in the Alias Table has to be used to find the right Identity to which this data should be attached.
  3. Unchanged User object and Contact with Eliapps Routing - Users with a Primary O365 account and a Secondary Eliapps account. The O365 alias data will generate the same data as in Case 1 above. The Eliapps aliases will generate a second row with the Case 2 data, but because it is a secondary Email account, IIQ has to create a second Contact object in AD to hold the Eliapps data since the User object is busy holding the O365 data.
  4. Routing "Junk" Contact objects - Entries in the Email Alias table that were not processed to generate a ProxyAddress in one of the previous three steps are grouped by unique MAILBOX value. Each MAILBOX value creates a "junk" Contact whose ProxyAddresses are the list of ALIAS_NAMEs that had that MAILBOX value. Note that this method of collection may combine Aliases owned by different Netids if they point to the same MAILBOX, but this is OK.

There is a fifth category of unprocessed aliases. Any Alias with a MAILBOX of "xxxx@connect.yale.edu" where the prefix xxxx is not a Netid must be a resource (a room, distribution list, etc.) and will not be processed. Exchange Online knows these things and handles them natively, so we don't have to create objects to inform Exchange about its own native stuff.

Any user can have Junk, so while each mail user Netid is either Case 1, 2, or 3, they can also have any number of Type 4 entries. Type 4 is grouped by MAILBOX and correlated to a Contact identified by the MAILBOX. It is not connected in any way to the Netid that owns the Alias. The junk aliases are spread across mailman, elilists, panlists, cs, som, aya, invest, med, physics, chem, geology, cmp, math, astro (all .yale.edu). Some of this is obsolete, but cleaning it up is future scope.

Users with an O365 or Eliapps account can delete it, and users with one type of account can get the other. So you can transition between Type 1 and 3, or 2 and 3. This is a delicate process because IIQ cannot directly move a field like ProxyAddresses from a User object to a Contact object in a single transaction (as would be possible with database SQL). This is, however, a manual process and becomes a function of the Mail System people. This code does not provide transition services but will provide documentation about how to make the transition correctly

Once you understand the four possible "packages" of mail routing data, the mechanism for gathering the data and passing it to IIQ is relatively simple. A SQL query of the Alias table (DIR_ONLINE_INFO) groups rows by MAILBOX. The AliasNames of the same MAILBOX are concatenated together in a string field. If the MAILBOX is "@connect.yale.edu" it is O365, if it is "@bulldogs.yale.edu" it is Eliapps, and if it is something else it is junk. The trick is then to create SQL clauses that flag primary accounts from secondary accounts, and distinguish Eliapps account that exist alone from Eliapps accounts belonging to someone who also has an O365 mailbox which have to be then assigned to a Contact. If we don't do this processing in SQL where it is easy, it becomes much more difficult in IIQ to know if an incoming Eliapps account record belongs to a Netid who also has an O365 record and therefore correlate it to or create a Contact Identity. If the SQL view has already done that analysis, IIQ can implement the correlation that the SQL has pre-processed.

The Alias table has bad data. We will remediate some problems and ignore issues that cause no problem for data delivery. The following list includes all the the things that need to be remediated, and some other interesting problems:

  • There were 555 users with O365 accounts and MAILBOX values of "AliasName@connect.yale.edu". They are to be changed to the more standard "Netid@connect.yale.edu".
  • There are Email Aliases to "Netid@connect.yale.edu" where the Netid User object does not appear to have an O365 mail account. Currently the Mail Relays forward mail to these addresses to Exchange Online, which bounces them because they have neither an O365 mail account nor a TargetAddress. This will continue to happen, although the new code will populate the MailNickName and ProxyAddresses field in Azure AD, whereas the old AD Daily Updater code would not populate these fields because the on premise AD did not have a RemoteMailbox indicator. We do not expect to continue to support the unnecessary on premise Exchange just to maintain the RemoteMailbox concept in the on premise AD. Although we have changed fields, the behavior where Exchange Online bounces the mail should be identical because the fields changed do not affect it.

We synchronize the on premise Local AD to the Azure AD. IIQ must provision changes to the Local AD and wait for the synchronization to occur within the next half hour. The only field in Azure AD that can be provisioned directly is UPN.

...

The "Mail" attribute in AD is not a technical field. It is the Email Address to be "published" in the directory. At Yale it is the PrimaryAliasName@yale.edu and that happens to be the O365 account of a two-mailbox user because we require O365 to be Primary if it exists.

...

Any personal O365 mail account

User Object

fieldvalues
MailNickNamePrimaryAliasName
TargetAddressSMTP:PrimaryAliasName@yaledu.mail.onmicrosoft.com
but it doesn't matter because when there is an O365 account
the targetAddress is .onmicrosoft.com (ignored by Exchange Online)
ProxyAddresses

SMTP:PrimaryAliasName@yale.edu
smtp: Netid@connect.yale.edu
smtp: PrimaryAliasName@connect.yale.edu
smtp: PrimaryAliasName@yaleedu.mail.onmicrosoft.com
smtp: O365Aliases@yale.edu (repeat for all secondary aliases to the O365 account)

Primary Eliapps with no O365 mail

User Object

fieldvalues
MailNickNamePrimaryAliasName
TargetAddressSMTP:PrimaryMailbox
ProxyAddresses

SMTP:PrimaryAliasName@yale.edu
smtp: EliappsAliases@yaleEliappsSecondaryAliases@yale.edu

Primary O365 with Eliapps Secondary

...

(repeat for all secondary aliases of the Eliapps account )


Eliapps account of someone with an O365 mail account

Contact Object

fieldvalues
MailNickNameGoogleAlias
TargetAddressSMTP:GoogleAccount@bulldogs.yale.edu
ProxyAddresses

SMTP:GoogleAlias@yale.edu
smtp: GoogleAliases@yaleGoogleSecondaryAliases@yale.edu (repeat)


Foreign Mail Alias

Contact Object

fieldvalues
MailNickNameAliasName
TargetAddressSMTP:Mailbox
ProxyAddresses

SMTP:AliasName@yale.edu

...