Wednesday, June 30, 2004

Installing Exchange System Manager on Windows XP - Part II

 

So there was already a great BLOG entry on this by Carol Swales What does it take to install admin only? and you are probably wondering "for cryin’ out loud, really how many entries do you need for installing ESM by itself on a workstation!"  You really only need one, I promise, but there is a corner case scenario that needs some additional explaining.

To explain it simply, if the following steps are taken as an upgrade path from XP SP1 to XP SP2, Exchange SMTP administration will be broken with the following error: "No Such Interface Supported".

1.      Install XP SP1

2.      Install IIS Snap-in (in Add/Remove Programs)

3.      Install XP SP2

4.      Install the Windows Server 2003 AdminPak

5.      Install Exchange System Manager Admin Only

Or

1.      Install XP SP1

2.      Install IIS Snap-in (in Add/Remove Programs)

3.      Install the Windows Server 2003 AdminPak

4.      Install XP SP2

5.      Install Exchange System Manager Admin Only

The reason your SMTP administration breaks is simple; you don’t have the SMTP snap-in installed.  If you’ll remember from Carol’s post she explains that on XP SP2 all you have to do is install the IIS snap-in, admin pack, and then ESM because in XP SP2 the IIS snap-in also installs the SMTP snap-in.  This is all true and good, however, if you’ve already installed the IIS snap-in PREVIOUS to installing XP SP2 you don’t get that groovy SMTP snap-in.  See, XP SP1 does not install the SMTP snap-in when you install the IIS snap-in.  However, this gets even stickier, our Exchange 2003 ESM Only setup knows you are on XP SP2 and says "hey they have the IIS snap-in installed, we know the SMTP snap-in installs with it, life is good".  Which of course, life is not.  We tried working with the IIS team to fix this and really, without going into a 20 page story about the Windows add/remove component and because Exchange 2003 setup had already shipped (you can’t fix setup in a service pack once we’ve shipped it) we were stuck with this behavior during this type of upgrade path.

Have no fear; there is a way to fix this.  You must re-install the IIS Snap-in and thus the IIS services which results in the SMTP Snap-In being installed (DLLs being registered).

OR

If you have other services in IIS you are using and you can’t do a reinstall you can manually register the following DLLs:

Seo.dll

Smtpadm.dll

Smtsnap.dll

- Amanda Langowski

Friday, June 25, 2004

More info on Shadow Copy in NT Backup vs. VSS/SIME

I have been neck deep in this topic for a couple weeks, so it is great that Nino Bilic (http://blogs.msdn.com/exchange/archive/2004/06/25/166104.aspx) wrote about this.  It supports my assumptions, but I would also like to add the issues around VSS and 3rd party products like SIME from EMC and their usefulness in production.  I spent a while thinking and documenting the reasons for DR scenarios and what type of recovery would be best.  Granted, VSS/SIME would work in all situations, but to work, the pain of recovery is too high in many cases.  Below is the post by Nino on his Blog and my research on the topic also.



 

My post on backups did not go into VSS backups and Exchange. Here are a few things about using VSS and Exchange, seeing that NTBackup comes with some "generic" shadow copy capabilities - a clarification of that functionality is in order:

 

- You physically can back up Exchange database files while online using NTBackup's generic shadow copy capabilities (W2K3/XPSP1 versions of NTBackup). This is not an "Exchange-aware" backup - NTBackup grabs the files like it does any other open file by using shadow copy. Therefore, this is NOT the recommended way to back Exchange up. It is essentially the same thing that you would get if you were using the "open file agent" from a 3rd party backup software. Additionally, if this type of backup is performed, you would have to make sure that the backup contains all drives where Exchange data lives on in order to have chance of successful restore.

 

- You can back up Exchange databases while online using NTBackup's Exchange-aware streaming backup API module (Online backup).

 

- Whether you do the backup with generic shadow copy capabilities or via the streaming API, the database will be "crash consistent" - meaning, it is marked as being in "Dirty Shutdown" state and must have log files replayed into it after restoration before it can be mounted. This "Dirty shutdown" state can be seen if you dump the database header using ESEUTIL /mh command. When databases do not require any logs to start, they are marked as being in "Clean shutdown" state. Please note here that if you restore a full online backup of the database and let the database go through the "recovery" (meaning the database replays the logs that were restored plus possibly some logs that were already on the disk) - the database will get into the "Clean shutdown" state without user intervention. That is why the previous post said that Online restores "just work".

 

- Backing up Exchange databases via the generic shadow copy capabilities that do not use the VSS framework that is provided in W2K3 is not supported or recommended. Yes, it can work, but it depends on you also capturing/preserving the right log files. You should exclude Exchange databases and logs from ordinary file backup to keep the backup from bloating and do a separate streaming API backup of Exchange, if NTBackup is your only backup solution. There's no time advantage in doing a generic shadow copy backup of the Exchange database, because NTBackup streams the file anyway even though it's a shadow copy, and you don't get checksum validation, preservation of necessary log files, etc.

 

- Exchange-aware VSS/shadow copy backups are available, but not with NTBackup - you must purchase a third party solution, and you must have special hardware capable of "snapping" the entire database backup very quickly (within ~20 seconds). Exchange does special things with the database to make it easier to backup reliably when you use an Exchange-aware solution (for example, every single physical database page is checksumed to make sure that we are backing up good information). When you do a garden variety shadow copy with NTBackup, the backup is streamed to tape or disk over a relatively long period of time, and Exchange has no idea that it is being backed up.

 

I hope this clarifies the difference between "generic" shadow copy functionality that NTBackup now comes with and the "full" VSS backup solution, as there is a big difference!

 

Nino Bilic




EMC Maintains a Snapping or Cloning technology for Exchange Server 2003 that utilizes Microsoft VSS technology.  The SIME solution completes a backup of sorts in the following basic process:

·         Checks the event logs on the host server to determine if any known database errors have been logged

·         If the above is ok, then ask VSS to acquiesce the Storage Group on the MetaLUN and Snapshot or clone the MetaLUN to an alternate location on the SAN.

·         Asks VSS to thaw the Storage Group and continue normal processing

·         Scans the databases that have been cloned by running ESEUTIL and checking for database consistency.

Recommended Usage

It is recommended to only use the SIME clone copy of the MetaLUN in the following disaster scenarios:

·         Entire Storage Group Failure / Corruption that is less than 4 hours old

·         Entire MetaLUN failure

·         Entire SAN failure

Exchange Server 2003 can natively be backed up using the Windows Server 2003 Backup solution.  This provides to disk or to tape backups. 

·         The backup software first contacts the Exchange System Attendant to ask it to start an online backup

·         The System Attendant acquiesces the databases and begins streaming the database information to the backup utility, which then streams it to an alternate disk location

·         Once the online backup has completed, the System Attendant thaws the databases and plays in logs that were used during the backup.

Recommended Usage

It is recommended to use the Windows Server 2003 Backup solution in the following disaster scenarios:

·         Single or Multiple Store Failure / Corruption

·         Single User Date Restore

·         Short term / Long Term Corruption (or possibly move users to a new Store and then re-create damaged database, then move users back)

 

Updated RPC Over HTTP Paper

Here is another updated MS Whitepaper showing the updates from SP1 to Managed RPC/HTTPS. This was a post from Neil Hobson at http://hellomate.typepad.com/exchange/2004/06/updated_rpc_ove.html

Microsoft has released an updated paper titled Exchange Server 2003 RPC over HTTP Deployment Scenarios. This guide describes four scenarios for deploying the Windows RPC over HTTP feature in a corporate environment, for both Exchange Server 2003 Service Pack 1, and Exchange Server 2003.

Several changes have been made - see the Overview section on the link for details.

Thursday, June 24, 2004

Webcast - Migrating eRooms Windows File Services and Exchange Public Folders to SharePoint - Level 300

This is a good presentation that I particularly needed to find out how to migrate eRoom to Sharepoint. It seems like there might be tools in the works for this, but it left a lot of questions unanswered. I guess we will have to get the Beta of these tools somehow and give them a try. Check it out!

Exchange 2000 ACL Mechanism

Here is part 2 of the ACL information from Larry Osterman  http://blogs.msdn.com/exchange/archive/2004/04/22/118377.aspx




Exchange 2000 ACL mechanism

This is part two of a three part series. See part one here.

When we set out to design the Exchange 2000 NT ACLs, the biggest task we faced was to determine what the correct values for the NT access rights should be.

We knew we had to be compatible with the existing 10 Exchange access rights - every access check semantic that could be expressed in Exchange 5.5 had to be able to be expressed in Exchange 2000.  So the logical interpretation was to simply bring the 10 access rights over from Exchange 5.5 and just stick them on the NT ACLs.  Since the NT access check mechanism allows for 16 access rights, we figured that would be easy.

Then we remembered IFS.

See, there's this amazingly cool feature in Exchange 2000 called IFS.  It exposes Exchange folders as if they're filesystem folders.  And the IFS team wanted to support security fully on the store, and they wanted to use Exchange's ACLs directly to do it (as opposed to rewriting the ACL before they handed it to the client).

This threw a huge wrench into the works because it added a whole other level of compatibility requirements.  Now Exchange access rights had to:

  • Be able to be mapped bidrectionally between Exchange 5.5 access rights

  • Be bit-wise compatible with the NT file-system access rights.

  • Be able to express all the semantics of Exchange that aren't present in the file-system.

Needless to say, we were in quite a pickle.  One major issue we had had to do with the NT native access rights themselves.  The NT filesystem access rights are as follows:

Access Right Bit pattern Applies to:

FILE_READ_DATA

0x0001 file & pipe

FILE_LIST_DIRECTORY

0x0001 directory

FILE_WRITE_DATA      

0x0002 file & pipe

FILE_ADD_FILE

0x0002 directory

FILE_APPEND_DATA

0x0004 file

FILE_ADD_SUBDIRECTORY

0x0004 directory

FILE_CREATE_PIPE_INSTANCE

0x0004 named pipe

FILE_READ_EA

0x0008 file & directory

FILE_WRITE_EA

0x0010 file & directory

FILE_EXECUTE

0x0020 file

FILE_TRAVERSE               

0x0020 directory

FILE_DELETE_CHILD       

0x0040 directory

FILE_READ_ATTRIBUTES

0x0080 all

FILE_WRITE_ATTRIBUTES

0x0100 all

NT defines 14 different access rights, but it also overlays the rights.  For example, the same access right that allows access to the data streams on a file is used to control if the user can see the contents of a directory.  Similarly, the same bit that's used to determine if a file can be opened for append access is used to control the creation of subdirectories.  In addition to those access rights, NT also defines 5 "standard" access rights:

DELETE 0x00010000L
READ_CONTROL 0x00020000L
WRITE_DAC 0x00040000L
WRITE_OWNER 0x00080000L
SYNCHRONIZE 0x00100000L

These access rights apply to all objects, not just files.  The "SYNCHRONIZE" access right isn't a proper "access" right, its an indication that the handle to the object being opened can be used synchronization.  The other three access rights protect various parts of the security descriptor in the object.

Fortunately, the Exchange access rights are similarly partionable - 5 of the 10 access rights (frightsReadAny, frightsEditAny, frightsDeleteAny, frightsEditOwned and frightsDeleteOwned) apply to the messages in a folder, 4 of the access rights apply to the folder (frightsCreate, frightsCreateSubfolder, frightsOwner, frightsVisible).  The remaining right (frightsContact) isn't really an access right - it's not used to grant or deny access to resources, but just a placeholder used to indicate that a particular user is a contact for the folder.

Taking each of the exchange access rights in turn, we realized that:

  • frightsReadAny - This right is sort-of a "read" access right.  It allows the user to read all the properties on any message in the folder.

  • frightsEditAny - This right is sort-of a "write" access right.  It allows the user to write any property on any message in the folder.

  • frightsDeleteAny - This maps nicely to the DELETE filesystem access right.

  • frightsEditOwned - This is "sort-of" like a write access, but it's conditional based on the "owner" of the message.

  • frightsDeleteOwned - This is "sort-of" like delete access, but again, it's conditional.

  • frightsCreate - This maps nicely to the FILE_ADD_FILE access right.

  • frightsCreateSubFolder - This maps nicely to the FILE_ADD_SUBDIRECTORY right.

  • frightsOwner - This one's kinda tough - it enables write access to all the properties in the folder.

  • frightsVisible - This property allows read access to the properties in the folder.

Next, we looked at the NT access rights.  Our big "aha!" was when we realized that there could be a one-to-many relationship between the exchange access rights and the NT access rights.  For example, on a file, there are three access rights that map to "read-like" access rights - FILE_READ_DATA, FILE_READ_EA, and FILE_READ_ATTRIBUTES.  Similarly, there are 3 write-like access rights - FILE_WRITE_DATA, FILE_WRITE_EA and FILE_WRITE_ATTRIBUTES.  So if we defined Exchange access rights for each of these "read-like" and "write-like" bits, we could simply map the exchange writes to ALL of them.  Similarly, we could make the same statements about the frightsOwner and frightsVisible access rights - they can be mapped to FILE_WRITE_ATTRIBUTE and FILE_READ_ATTRIBUTE respectively.  So we were 90% of the way done with figuring out what to do.

Once we decided that we were going to map single access rights to multiple access bits, we needed to figure out what each of the NT filesystem access rights would mean to the Exchange store.

We started with the read access rights: FILE_READ_DATA, FILE_READ_EA, and FILE_READ_ATTRIBUTES.

FILE_READ_DATA protects access to the file's data streams. The closest analog to this in Exchange are the properties that make up the "body" of the message.  Ok, so far so good.  But what are "attributes" and "extended attributes" on a message?  Some of the properties like PR_ATTR_READONLY were obvious - it's used to map to the read-only filesystem attribute, so it's clearly an attribute, but what about the other ones.

We decided to make a totally and absolutely arbitrary decision.  We defined a specific set of properties as "attributes", a specific set of properties as "body" properties, and all the others we classified as either "extended attributes" or "body" properties depending on whether or not the property was transmittable.

Exchange 2000 Access Mask

When we were finally done and the dust had settled, we had settled on twenty-two access rights, but many of them overlap.  We finally ended up with:

The Exchange Platinum access rights are:

fsdrightReadBody† 0x00000001 The ability to read the “body” of a message.
fsdrightListContents‡ 0x00000001 The ability to open a contents table.
fsdrightWriteBody† 0x00000002 The ability to modify the “body” of a message.
fsdrightCreateItem‡ 0x00000002 The ability to create new messages
fsdrightAppendMsg† 0x00000004 The ability to append data to a message
fsdrightCreateContainer‡ 0x00000004 The ability to create  a subfolder
fsdrightReadProperty 0x00000008 The ability to read properties on the folder/message.
fsdrightWriteProperty 0x00000010 the ability to write properties on the folder/message.
fsdrightExecute† 0x00000020 The ability to “execute” the body of a message
fsdrightReserved1‡ 0x00000040 The ability to delete arbitrary items under this folder
fsdrightReadAttributes 0x00000080 The ability to read the “attributes” of a folder/message.
fsdrightWriteAttributes 0x00000100 The ability to modify the “attributes” of a folder/message.
fsdrightWriteOwnProperty† 0x00000200 The ability to modify messages that the principal granted this right has created.
fsdrightDeleteOwnItem† 0x00000400 The ability to delete messages that the principal granted this right has created.
fsdrightViewItem 0x00000800 The ability to see the items in the folder.
fsdrightOwner‡ 0x00004000 No security semantics, used to indicate the “owner” of a folder.
fsdrightContact‡ 0x00008000 No security semantics, used to indicate “contacts” for a folder – people that are not the owner, but are responsible for the folder.
fsdrightWriteSD WRITE_DAC Alias for NT “WRITE_DAC” right.
fsdrightDelete DELETE Alias for NT “DELETE” right.
fsdrightWriteOwner WRITE_OWNER Alias for NT “WRITE_OWNER” right.
fsdrightReadControl READ_CONTROL Alias for NT “READ_CONTROL” right.
fsdrightSynchronize SYNCHRONIZE Alias for NT “SYNCHRONIZE” right.

Access rights that apply only to messages have a † symbol after their name; access rights that apply only to folders have a ‡ symbol after their name.  If an access right does not have a symbol, it applies to both messages and folders.

Putting it all together

Ok, so now that we've defined the Exchange 2000 access rights, we needed to set up the mapping between Exchange 5.5 access rights and Exchange 2000 access rights.  If we can't do that, we can't even begin to attempt to convert ACLs from Exchange 5.5 to Exchange 2000

So here's what we finally came up with:

Exchange 5.5 Rights

Exchange 2000 Rights

frightsReadAny

fsdrightReadControl fsdrightReadBody  fsdrightReadAttributes  fsdrightReadProperty  fsdrightViewItem fsdrightSynchronize fsdrightExecute

frightsCreate

fsdrightCreateItem

frightsEditOwned

fsdrightWriteOwnProperty

frightsDeleteOwned

fsdrightDeleteOwnItem

frightsEditAny

fsdrightReadControl fsdrightWriteBody fsdrightWriteAttributes fsdrightWriteProperty fsdrightAppendMsg fsdrightCreateItem fsdrightDelete fsdrightCreateContainer fsdrightOwner fsdrightSynchronize fsdrightWriteSD fsdrightWriteOwner

frightsDeleteAny

fsdrightDelete

frightsCreateSubfolder

fsdrightCreateContainer

frightsOwner

fsdrightOwner fsdrightWriteProperty fsdrightWriteSD fsdrightDelete fsdrightWriteOwner fsdrightWriteAttributes fsdrightViewItem

frightsContact

fsdrightContact

frightsVisible

fsdrightViewItem



And the reverse mapping table (used when converting between an NT security descriptor into an Exchange ACL):

EXCHANGE 2000 ACCESS RIGHTS

Exchange 5.5 access rightS

fsdrightReadBody

Ignored

fsdrightListContents

Ignored

fsdrightWriteBody

Ignored

fsdrightCreateItem

frightsCreate

fsdrightAppendMsg

Ignored

fsdrightCreateContainer

frightsCreateSubfolder

fsdrightReadProperty

frightsReadAny

fsdrightWriteProperty

frightsEditAny

fsdrightExecute

Ignored

fsdrightReserved1

Ignored

fsdrightReadAttributes

Ignored

fsdrightWriteAttributes

Ignored

fsdrightWriteOwnProperty

frightsEditOwned

fsdrightDeleteOwnItem

frightsDeleteOwned

fsdrightViewItem

frightsVisible for folders, ignored on messages

fsdrightOwner

frightsOwner

fsdrightContact

frightsContact

fsdrightWriteSD

Ignored

fsdrightDelete

frightsDeleteAny on messages

fsdrightWriteOwner

Ignored

fsdrightReadControl

Ignored

fsdrightSynchronize

Ignored




A quick note: frightsOwner only granted if ALL the folder owner rights are present – fsdrightOwner fsdrightWriteProperty fsdrightWriteSD fsdrightDelete fsdrightWriteOwner fsdrightWriteAttributes fsdrightViewItem.

Well, that's the basics on access rights.  I don't quite know how it got this long but...

The next column pulls it together and describes how we convert from Exchange 5.5 ACLs into Exchange 2000 ACLs. (See first column)

- Larry Osterman

ACL Conversion - Part 1

This was originally posted on http://blogs.msdn.com/exchange/archive/2004/03/17/91454.aspx




Exchange 5.5 Security

When an Exchange client contacts the Exchange 5.5 store, the Exchange client specifies an Exchange DN to represent the user on the Exchange server.  The NT user’s account is validated to ensure that it has the “receive-as” right to that object in the Exchange 5.5 directory service.  From that point on, the user is identified by their DN and not by their NT account.

Exchange 5.5 only supported security on folder objects; access rights for the messages in a folder were defined by the access rights on the folder itself.

Exchange 5.5 Access Rights

Exchange 5.5 supports ten distinct access rights.  The access rights are:

  • frightsReadAny (0x0000001L) – The ability to read any message in the folder.
  • frightsCreate (0x0000002L) – The ability to create items within the folder.
  • frightsEditOwned (0x0000008L) – The ability to modify items created by the user within the folder
  • frightsDeleteOwned (0x0000010L) – The ability to delete items created by the user within the folder.
  • frightsEditAny (0x0000020L) – The ability to modify any items in the folder
  • frightsDeleteAny (0x0000040L) – The ability to delete any items the folder
  • frightsCreateSubfolder (0x0000080L) – The ability to create folders underneath the folder.
  • frightsOwner (0x0000100L) – The ability to modify the properties of the folder itself.  This includes the right to delete the folder.
  • frightsContact (0x0000200L) – This is not an access right at all, instead it is administrative functionality implemented in the ACL on a folder.
  • frightsVisible (0x0000400L) – The ability to see the folder in a hierarchy table - this right was added in Exchange 5.0

Careful examination of the access rights reveals that five of the access rights apply to the items in the folder (frightsReadAny, frightsEditOwned, frightsDeleteOwned, frightsEditAny, and fRightsDeleteAny), and five of the access rights apply to the folder itself (frightsCreate, frightsCreateSubfolder, frightsOwner, frightsContact, frightsVisible).

The two “owner” rights (frightsEditOwned and frightsDeleteOwned) are critical when implementing a discussion folder.  In that scenario, a user should be allowed to modify (or delete) messages that they created, but they should NOT be allowed to modify (delete) items that another user has created.

Exchange 5.5 ACLs

In Exchange 5.5, an ACL was simply an unordered list of DN’s and their associated Exchange rights.  The membership of an ACL was exposed to a client via the IExchangeModifyTable interface and via the PR_ACL_DATA and PR_EXTENDED_ACL_DATA properties.

Exchange 5.5 Access Check

Exchange 5.5 implemented a “most specific”->”least specific” access check algorithm.  If a user was explicitly mentioned in an ACE (their DN appeared in the ACL), then the ACE contained the complete set of access rights for that user.  If the user was NOT listed in the ACL, then the users rights were calculated by combining (with a logical OR) all the rights for the groups in the ACL of which the user was a member.  If the user wasn’t explicitly listed in the ACL, and wasn’t a member of the groups listed in the ACL, then the users rights were calculated from the default rights on the folder.

For example, consider what happens to the following set of 4 users:

  • User 1: Member of Group A and Group C
  • User 2: Member of Group A
  • User 3: Member of Group B
  • User 4: Not a member of group.

In addition, Group C is a member of Group A.  Pictorally, this can be represented as:

So what happens when each of these users attempts to access a folder with the following ACL:

Group B: Read, Write
User 3: Read, Delete
Group C: Delete, Create Items
Group A: Read, Create Subfolder
Default: Delete Own Item, Edit Own Item

 

The access rights for the users in this example are as follows:

  • User 1 – Read, Write (from Group B), Delete, Create Items (from Group C), Create Subfolder (from Group A)
  • User 2 – Read, Create Subfolder (from Group C)
  • User 3  - Read, Delete
  • User 4 – Delete Own Item, Edit Own Item

Wednesday, June 23, 2004

Exchange 2000 ACL conversion

http://blogs.msdn.com/exchange/archive/2004/06/23/163895.aspx | Comments


(This is a part 3 of the series. Go here for part one and here for part two)

I've spent a far amount of time talking about how access rights work in Exchange 2000, and how they worked in Exchange 5.5.

Now I'm going to focus on how we put all the pieces together to make this whole thing work. Hang on tight, it's a bit of a wild ride.

First off, I'm going to assume that you understand how NT's access check mechanism works. As a quick refresher, here's the meat of the access check process.

Every object has a security descriptor. The security descriptor contains 4 pieces of information. The "OWNER", "GROUP", "System Access Control List" and the "Discretionary Access Control List". The Access Control Lists (ACLs) define access rights to the object, the System ACL describes the auditing semantics of the object (whether or not access to the object is audited or not). The Discretionary ACL defines who can have access to the object.

An ACL is an ordered collection of Access Control Entries (ACEs). Each ACE contains four pieces of information: The type of the ACE, flags for the ACE (more on these later), the access rights that are controlled by the ACE, and the SID of the security principal to whom the ACE applies (a security principal is NT security-talk for a user or group).

There are in general, two types of ACEs that will appear in a discretionary ACL: ACCESS_ALLOWED ACEs and ACCESS_DENIED ACEs. What a surprise - ACCESS_ALLOWED ACEs grant access to an object, and ACCESS_DENIED ACEs deny access.

A quick digression: This is an over simplification of ACEs - there are actually 4 types of ACEs that appear in a DACL, but they don't affect this discussion (but I do feel obligated to point this out :)). At some time in the future I'll discuss object ACEs and why they're so utterly cool.

When NT does it's access check, it iterates through the ACEs in the DACL for the object, checking to see first if the principal in the ACE is active in the users token. In other words, if the SID in the ACE is the SID of the user making the check, or if the SID is for one of the user's active groups (in Windows 2000 and above, group membership can be excluded from access checks).

If the principal in the ACE is active in the users token, it next checks to see if the access rights that are being requested are included in the access mask. If they're not, it skips to the next ACE. If they are, NT next checks the ACE type. If it's a grant ACE, then it turns off the bits in the desired access mask. If it's a deny ACE, then it denies access.

When the access check code gets to the end of the ACEs, it checks to see if any of the requested access rights are still turned on - if that's the case, it denies access (because one of the desired access rights wasn't granted by an ACE).

Ok, with that behind us, now it's time for the ride to start.

Remember that Exchange 5.5's access check is a most-specific to least specific access check. This means that first exchange looks to see if a user is specifically mentioned in the ACL, then if a group the user's a member of is in the ACL, then it tries the rights for the user "everyone".

So if we're going to use NT's access check mechanism, we want to model the ACLs after the Exchange ACLs. We're going to want to break up the ACL into three sections:

Section 1 - The rights granted to USERS.
Section 2 - The rights granted to GROUPS.
Section 3 - The rights granted by default to the folder.
And we want to put them in that order - since NT's access check evaluation goes in order, we want to emulate the ordering that Exchange uses.

First let's consider section 3, since it's easiest. Section 3 can be implemented with a single ACE that grants access to the "EVERYONE" user.

Cool, that's 1/3rd of the problem done :)

The next thing to tackle is the rights to users. The Exchange semantics for users says that if the user is in the ACL, then the exchange ACE defines the complete set of rights for that user. So we clearly need a grant ACE that grants access to the user in the Exchange ACL.

But what if the exchange user is a member of a group that's listed further down in the ACL? We don't want the access check to continue and find those ACEs, since the user wouldn't have those rights in Exchange 5.5. So we've got to find a way of "stopping" the ACL evaluation. Hmm... It is a puzzlement.

But wait! What about a deny ACE? As I mentioned above, if the rights listed in a deny ACE are requested, then the access check function will stop evaluating immediately. So what if we use a PAIR of access rights. One that grants the user the rights that correspond to the Exchange 5.5 rights, and the other that DENIES that user every right that isn't granted. In other words, and ACE that's just there to force the access check logic to terminate. That will work!

So we're 2/3rds of the way there. For section 1, we take each user mentioned in the Exchange 5.5 ACL and create a pair of ACEs - one that grants the user the rights that correspond to the rights they have, and a stopper. For section 3, we add an ACE that grants Everyone the rights that correspond to the "default" rights. Now what about groups.

Groups function additively in the Exchange access check mechanism. The user is granted the access rights granted to all the groups they're in (so if the user is in groups A, B, and C, and the ACL grants group A frightsReadAny access and group C frightsWriteOwn access, the user gets frightsReadAny|frightsWriteOwn access).

Well, the NT access check mechanism does that - it iterates through access allowed ACEs trying to see if each of the rights in the ACE is granted to the user. So we can just turn the group ACLs into access allowed ACEs and just put the access allowed ACEs together.

But what about a situation where a group is allowed frightsReadAny rights to a folder but default was granted frightsWriteAny (a silly scenario, but possible)? In this case, the user wouldn't have write any access to the folder, they'd only have read any access. So we need another set of "stopper" ACEs. But we need to put the stopper ACEs AFTER the last of the group ACEs, and we need to put them in a group together before the final default ACE.

Phew, that's a lot. So the bottom line is that when we convert the Exchange 5.5 ACL to an NT security descriptor, we need to form an ACL with the following format:

REPEAT
GRANT User rights
DENY User
Inverse(rights)
GRANT User rights
DENY User Inverse(rights)
REPEAT
GRANT Group rights
GRANT Group rights
REPEAT
DENY Group Inverse(rights)
DENY Group Inverse(rights)
REPEAT <0 or 1>
GRANT Everyone rights

An ACL that has this form is called an "Exchange Canonical ACL".

So to convert an Exchange 5.5 ACL to an Exchange 2000 ACL, the first thing to do is to sort the Exchange 5.5 ACL into three groups: Users, Groups, and default. For each user, create an NT ACCESS_ALLOWED_ACE that grants the Exchange 2000 rights that correspond to the user's 5.5 rights. Then add an NT ACCESS_DENIED_ACE that denies any rights that weren't allowed. Next, for each group, add an ACCESS_ALLOWED_ACE for the group (with the corresponding rights). Now loop through the groups again, and add an ACCESS_DENIED_ACE for each ACE listed above. And finally, if the Exchange 5.5 had a default ACL, add an ACCESS_ALLOWED_ACE granting EVERYONE the rights that correspond to the default rights.

So we're done, right?

Nope. I did say this was a bit of a roller coaster ride.

Remember that the Exchange access rights were broken down into two sets - the rights that apply to folders and the rights that apply to the messages in that folder. Unlike the native filesystems, Exchange effectively had dynamic inheritance. A quick aside: dynamic inheritance means that when the ACL of the parent object (the folder) changes, the ACL of the objects contained in the folder also change. The Active Directory implements dynamic inheritance, NT's filesystems implement static inheritance.

In the original design of the Exchange ACL conversion mechanism, the folder actually had TWO ACLS on it - one was the folder ACL, which was constructed as described above. The other ACL was called the "default message ACL". The idea was that for any message that didn't have an ACL, we'd go to the folder containing the message, retrieve the default message ACL on that folder and use that instead.

Unfortunately, the test team felt that this was too confusing, and they were concerned that the two ACLs could get out-of-sync (a very valid concern btw). So we decided to combine the folder ACL and the default message ACL into a single ACL.

How could we do that? We overloaded the access rights in the Exchange 2000 access rights - some of the bits apply to the folder, and the same bits apply to messages in the folder!

Well, it turns out that the NT ACL design comes to our rescue. Remember how I mentioned flags in the ACE above? It turns out that there are 5 ACE flags:

OBJECT_INHERIT_ACE
CONTAINER_INHERIT_ACE
NO_PROPAGATE_INHERIT_ACE
INHERIT_ONLY_ACE
INHERITED_ACE

Now we don't need to consider most of the flags, but there are a couple of interesting flags. In particular, there's the INHERIT_ONLY flag which indicates that the ACE should be ignored on an access check - cool! We have a way of "hiding" ACEs from AccessCheck. The next ACE flag of interest is the OBJECT_INHERIT_ACE - this indicates an ACE that applies to objects in a container (or messages in a folder!).

Aha! So we can do this - we take all the ACEs that would normally have been put in the default message ACL and we put them into the folder ACL with the OBJECT_INHERIT_ACE flag AND the INHERIT_ONLY_ACE flag. Then when we're calculating the ACL for a message that doesn't have it's own ACL, we can ask NT to run the ACL inheritance algorithm over the folder's ACL to come up with ACL for the message! Voila!

So are we there yet? Well no, not quite.

The idea of paired rights above is pretty cool. But there's a bit of a problem. It turns out that there are a number of tools like CACLS that really don't like ACEs with 0 access rights in them. And if a user (or group) is granted full rights above, then the "stopper" ACE will have 0 rights. So the rules for forming the ACL were relaxed slightly - if the set of rights granted or denied was 0, then the ACL conversion logic would omit the 0 rights ACE.

And that, in a nutshell is how the wacky Exchange 2000 folder ACLs came to be.

Larry Osterman

Welcome to Nothin but Exchange (NbE)

Hi all! Why is this blog here and why would you care? Let me explain. I am an experienced enterprise architect with Horizons Consulting (http://www.hrizns.com) and constantly look for and find great data on doing all sorts of things with Exchange, from design ideas to appliations, to detailed troubleshooting. The problem is, this information is scattered all over the web. It is hard to find when you really need it. So, I will try my best to cross link all of this great data so that on one weblog we can find almost anything! Wish me luck!!