This article is addresses a specific problem related to security of Microsoft Exchange Server: the ability to programmatically set permissions on folders in the Exchange information store.
To perform such an operation manually, Exchange Server administrator may use Exchange System Management (ESM) utility, which is a part of Exchange Server installation:
- Create public folders aaa and bbb with ESM, and create users with mailbox userAAA and userBBB in the Active Directory.
- Then in ESM, open aaa Properties dialog by selecting Folder Properties item in the right-click menu on public folder aaa.
- Activate Client Permissions dialog (depicted in figure below) by pressing the appropriate button.
- Using Add..., Remove... and Properties... buttons, modify roles and permissions given to users userAAA and userBBB on folder aaa (see figure below).
I faced this problem (among many others) while developing a component for managing Active Directory and Exchange Server. Starting to deal with the problem, I thought that all I needed was to take a huge and generally well written book  by Thomas Rizzo and just find some ready-made solution there. Unfortunately, it was not the case. First, I found in the book the following information:
How you created the format for your security descriptor will depend on whether you are working in a MAPI public folder top-level hierarchy (TLH) or a non-MAPI TLH. A MAPI TLH requires that you create your security descriptor using the MAPI canonical format. This is what clients, such as Outlook, expect to see: the importance of this requirement cannot be overemphasized. If you create your security descriptor using the Windows canonical format, you will break Outlook! It is also possible to lock yourself out from being able to modify existing items or folders. Therefore, you must be very careful when you work with security descriptors. I highly recommend that you just take advantage of the Security Module that ships with the Exchange SDK. It understands how to correctly create both MAPI and Windows canonical formats and includes code to make sure you don't do any harm when working with security descriptors. (Page 890).
Naturally, after such a strong warning and recommendation, I found information about the Exchange SDK Security Module. In the same chapter, I read the following.
The Exchange SDK Application Security Module
And then, of course:
If these shortcomings don't affect you, the security module makes the task of working with security easy.
Brief Solution Description
Pretty soon, I found a Microsoft sample  that seemed to answer my problem. It actually did the job. The only thing left was to operate it remotely on behalf of an account with MAPI profile [3, 4] for Exchange. I chose .NET Remoting technique (unlike IIS WebService, Remoting allows us to run software on behalf of a particular account easily). I wrapped up the sample code in COM in-proc server and put it to my .NET object exported with Remoting. First, I tried to use Multi-Threaded Apartment (MTA) COM wrapper changing MAPI initialization according to [5, 6] recommendation. But apparently, Exchange SDK does not support MTA access:
HrOpenExchangePublicStore() method failed with “Unknown Exception” return code. So, the COM STA containing Microsoft sample  code exported with Remoting technique seemed the only choice.
Using the Code
The sample solution consists of the following projects:
ClientPermissionHelper. COM STA component wrapped up in Exchange SDK sample ; implements
IPermission interface containing
Remove() methods to deal with permissions. For the sake of simplicity (and because performance is not the main concern for this sample), the component is designed stateless. It implies that each of the interface methods initializes MAPI, creates a MAPI session, does the job, and then releases session and un-initializes the MAPI connection. For the real world applications, a more sophisticated design may be adopted.
ClientPermissionHelper uses MAPI profile for Exchange, named "MS Exchange Settings" (name is hardcoded in the sample). The component uses Exchange SDK header files and static libraries that make it difficult to build it in VS .NET. To cope with this, the relevant header files are placed in the Include folder under the project main folder, and static libraries are paced in Lib folder, with appropriate changes in the project settings (thanks to Yuval Nahon who patiently solved the problem).
ClientPermission. .NET wrapper for
ClientPermissionHelper using COM Interop; exported with Remoting technique and, as such derived from
MarshalByRefObject class. The component implements
IClientPermission interface which is defined in
SvrInterface and consumed by Remoting client. Only one instance of COM object may be used since COM Interop automatically marshals calls from different threads of Remoting built-in thread pool to STA COM thread (of course, at the expense of some performance penalty).
IClientPermission interface and
Permissions enumerator used by both Remoting server and client.
ClientPermission component and provides its export. It may run on Exchange machine either as a normal application (with /console parameter in command line) or as a Windows service. In both cases, SrvHost should run under the account which has a valid MAPI profile for Exchange (named "MS Exchange Settings"). The component registers an HTTP channel with port number hard-coded for simplicity. In case of Windows service, SrvHost is registered under the name
ESClientPermissionServer as shown in the figure below:
Client. Manages Exchange permissions by calling methods of
IClientPermission interface implemented in
InstExchProfile. Utility for creation of MAPI Exchange profile (as shown e.g., in ) named "MS Exchange Settings".
InstExchProfile have to be placed on the Exchange machine,
Client has to be placed on the client machine, and
SrvInterface on both.
In order to prepare a sample to run, the following steps should be performed:
- Build solution (make sure that ClientPermission project contains reference on ClientPermissionHelper COM Interop).
- Place ClientPermissionHelper.dll, ClientPermission.dll, SrvInterface.dll, SrvHost.exe and InstExchProfile.exe on Exchange machine, and Client.exe and SrvInterface.dll on client machine.
- Register COM ClientPermissionHelper.dll on server machine if it was not done during build. It may be done with either RegSvr32 utility or using ClientPermissionHelper.bat file from SrvHost\bin\Release or SrvHost\bin\Debug.
- Set up "MS Exchange Settings" Exchange profile on Exchange machine with InstExchProfile utility.
- If you are planning to run SrvHost.exe as Windows service, then it has to be installed as a service either with InstallUtil utility or using the file InstallService.bat under account with "MS Exchange Settings" Exchange profile on Exchange machine.
- Create manually public folder aaa and bbb on Exchange, and users userAAA and userBBB with mail boxes in Active Directory. In order to check that this is done correctly, try to add/modify/remove some permission on aaa and bbb for userAAA and userBBB manually.
To run the sample:
- Start SrvHost.exe either as a service or as an EXE application (with key /console or using file SrvHost.bat). If server is running as normal application, then it outputs log information to debug view. Thus DbgView utility may be useful.
- Run Client.exe on client machine.
As a result, permission on aaa and bbb for userAAA and userBBB should be changed appropriately.
The above described approach actually solves the problem. But it would be also interesting to try to use
ACE  and
ACLObject  COM co-classes implemented in ACE.dll first shipped with Microsoft Exchange 5.5. Several publications (e.g., [9, 10 and 11] to mention just a few) describe various operations with Exchange folder permissions locally on Exchange machine. It might be probably possible to use these components from
ClientPermission with COM Interop instead of
This article describes a way to remotely modify permissions on folders in the Exchange Server information store. To attain this, a special Exchange SDK-based COM in-proc server that actually does the job is designed. It is wrapped into a .NET class exposed to a client with Remoting technique.
-  Programming Microsoft Outlook and Microsoft Exchange 2003, Third Edition / Thomas Rizzo. (1074 pages).
-  How To Modify Exchange Folder Permissions Using
-  Demystifying Exchange 2003 Custom Recipients, DLs, and Profiles.
-  Configure MAPI profile parameter.
-  FIX:
MAPIInitialize() Fails with
MAPI_NO_COINIT Flag To Make
MAPIInitialize Not Call
-  Minding the E-Mail by Bill Boswell, December 2003.
-  How To Add A Delegate To An Exchange Folder with the ACL Component and CDO (1.21) (295558).
-  PRB: ACL: Outlook 2000 Doesn't Properly Read ACL Settings (237924)