Are you a world traveler? ZoneTick is a cool utility that'll help you stay in touch over multiple time zones!
 
Using IExchangeFolderACLs to Modify Public Folder Access  
Nik Okuntseff  MS Exchange Server Programming 

Using IExchangeFolderACLs to Modify Public Folder Access

Let us see how IExchangeFolderACLs interface may be used to read and modify access control entries for a public folder. The following code fragment demonstrates reading and dumping access masks. The code assumes that MyPublicFolder exists in All Public Folders. You should either create one or change pszFolder variable accordingly.
 

Reading Contents of a Public Folder ACL

#include <afxwin.h>
#include <edk.h>

int main()
{
    /*
     * Algorithm:
     *  1. Determine ENTRYID for the folder.
     *  2. Use HrFolderACLsOpen to get IExchangeFolderACLs.
     *  3. Scan all members and dump their rights.
     */
 
    char * pszFolder = "@PR_IPM_SUBTREE_ENTRYID\\All Public Folders\\MyPublicFolder";

    HRESULT hr;
    LPMAPISESSION pSession = NULL;

    // Initialize MAPI
    hr = MAPIInitialize(NULL);
    if (FAILED(hr)) throw -1;

    // Obtain MAPI session
    hr = MAPILogonEx(0,    // Handle to parent window
      "MS Exchange Settings", // Profile name
      NULL,   // Password
      MAPI_NEW_SESSION |
      MAPI_EXTENDED |
      MAPI_LOGON_UI, // Logon flags
      &pSession);  // Resulting MAPI session
    if (FAILED(hr)) throw -1;
 
    // Open Exchange public message store
    LPMDB pPublicMsgStore = NULL;
    hr = HrOpenExchangePublicStore(pSession, &pPublicMsgStore);
    if (FAILED(hr)) throw -1;

    // Find the folder
    ULONG cbEid = 0;
    LPENTRYID pFolderEid = NULL;
    hr = HrMAPIFindFolderEx(pPublicMsgStore,
       '\\',
       pszFolder,
       &cbEid,
       &pFolderEid);
    if (FAILED(hr)) throw -1;

    // Use HrFolderACLsOpen to get IExchangeFolderACLs.
    LPFOLDERACLS pFolderACLs = NULL;
    hr = HrFolderACLsOpen(pSession,
       pPublicMsgStore,
       cbEid,
       pFolderEid,
       &pFolderACLs);
    if (FAILED(hr)) throw -1;

    // Use IExchangeFolderACLs to dump ACL
    LONG lRights = 0;
    LPSTR pszDisplayName = NULL;
    LPENTRYID pAclEid = NULL;
    hr = pFolderACLs->HrGet(&lRights,
       &pszDisplayName,
       &cbEid,
       &pAclEid);
    while (SUCCEEDED(hr))
    {
        printf(pszDisplayName);
        printf(" rights: 0x%08X\n", lRights);

        hr = pFolderACLs->HrGet(&lRights,
           &pszDisplayName,
           &cbEid,
           &pAclEid);
        if (pAclEid)
       {
            MAPIFreeBuffer(pAclEid);
            pAclEid = NULL;
        }
    }

    // Cleanup
    if (pFolderACLs)
        pFolderACLs->Release();
    if (pFolderEid)
        MAPIFreeBuffer(pFolderEid);
    if (pPublicMsgStore)
        pPublicMsgStore->Release();
    if (pSession)
        pSession->Release();

    return 0;
}

Let us see what is happening here. First, I open public message store and locate the folder ENTRYID. The I use it to obtain IExchangeFolderACLs interface. This is accomplished with help of the HrFolderACLsOpen function. Then I use its HrGet method to scan through all entries.

After I have run this code I saw that the first two entries in ACL don't have either pszDisplayName or ENTRYID. These two entries are special cases. They are reserved for the Default and Anonymous access.
 

Modifying Access Rights

Let's us see how we could modify access rights for a mailbox. The following fragment is taken from my Security/IExchangeFolderACLsModify sample. The code scans through the list to locate our test entry first. Then I set up the position with the HrSeek call and use the HrModify method.
 
char * pszMailboxToModify = "Test"; // We'll modify rights for this mailbox

// Use IExchangeFolderACLs to modify rights
LONG lRights = 0;
LPSTR pszDisplayName = NULL;
LPENTRYID pAclEid = NULL;
LONG lPos = 0; // Current position
hr = pFolderACLs->HrGet(&lRights,
       &pszDisplayName,
       &cbEid,
       &pAclEid);
while (SUCCEEDED(hr))
{
    int iRes = memcmp(pszMailboxToModify, pszDisplayName, 1 + strlen(pszMailboxToModify));
    if (0 == iRes)
    {
        // We have located the entry to modify.

        // Set position
        hr = pFolderACLs->HrSeek(lPos);
        if (FAILED(hr)) throw -1;
 
        // Modify rights
        hr = pFolderACLs->HrModify(rightsAll, NULL);
        if (FAILED(hr)) throw -1;
        break;
    }
 
     hr = pFolderACLs->HrTell(&lPos);
     if (FAILED(hr)) throw -1;

    hr = pFolderACLs->HrGet(&lRights,
       &pszDisplayName,
       &cbEid,
       &pAclEid);
    if (pAclEid)
    {
        MAPIFreeBuffer(pAclEid);
        pAclEid = NULL;
    }
}

You need to be a folder owner to modify rights for other accounts. This means that your own rights set should contain frightsOwner. A folder may have many owners. This is similar to Windows NT security - in order to modify permissions for other accounts you own accounts should be powerful enough, otherwise the operation fails.
 

[ Contents | Home ]

Send comments and suggestions to niko@wrconsulting.com
Copyright © 1997-1998 by Nik Okuntseff