Client Experience: Free Busy not working

Worked on the Free / Busy issue recently and thought to share troubleshooting steps. Free / Busy usually is "black box" for a lot of Exchange folks I was talking with, but essentially it is really easy and straight forward service to troubleshoot. I'm planning to write article about it and most common troubleshooting scenarios in future.

Now, back to the case. FB access was working for entire org, just several users were suffering FB issues. UserA couldn't see FB of UserB and UserC... And vice versa. Other users could see FB for UserA, UserB... All users were part of the same Exchange organization.

With above, conclusion was that probably permission level issues were in place. Fiddler trace confirmed suspicious:

 <FreeBusyResponse><ResponseMessage ResponseClass="Error"><MessageText>Microsoft.Exchange.InfoWorker.Common.Availability.NoFreeBusyAccessException: The caller does not have access to free/busy data.<br>. Name of the server where exception originated: SERVER01. LID: 44348</MessageText><ResponseCode>ErrorNoFreeBusyAccess</ResponseCode><DescriptiveLinkKey>0</DescriptiveLinkKey><MessageXml><ExceptionType xmlns="http://schemas.microsoft.com/exchange/services/2006/errors">NoFreeBusyAccessException</ExceptionType>

Fired PowerShell session to check permission and to my surprise, permissions seemed OK:

 Get-MailboxFolderPermission userA:\calendar
 
FolderName           User                 AccessRights
----------           ----                 ------------
Calendar             Default              {AvailabilityOnly}
Calendar             UserB                {Reviewer}
Calendar             UserC                {Reviewer}
Calendar             UserD                {Reviewer}
Calendar             UserF                {Reviewer}

For all users that was working, ACL wasn't present which means they are going to fail to "Default" scope and get "AvailabilityOnly". Other users that have permissions shouldn't get "NoFreeBusyAccessException" as ACL allows them "FullDetails" with "Reviewer" permissions. Only one strange thing I found here is that default "Anonymous" permission of "None" is missing, but that shouldn't matter at all since all users within same Exchange organization should have authenticated session.

Going forward I wanted to compare raw store level permission with what Get-MailboxFolderPermission cmdlet was showing. In order to do that, Get-StoreQuery should be used and steps as outlined below:

1. Find MailboxNumber within store:

 $userMbx = Get-Mailbox user@domain.com
Get-StoreQuery -Database $userMbx.Database -Query "Select MailboxNumber from Mailbox Where MailboxGuid='$($userMbx.ExchangeGuid)'"

MailboxNumber
-------------
          194

2. Find Calendar folder in the store:

 $userMbxFolder = Get-StoreQuery -Database $userMbx.Database -Query "Select * From Folder Where MailboxNumber=194 and DisplayName='Calendar'"

3. Parse Folder ACL blob:

 $userMbxPerms = Get-StoreQuery -Database $userMbx.Database -Query "Select * From ParseAclTableAndSD($($userMbxFolder.AclTableAndSecurityDescriptor))"

$userMbxPerms.Value

ACL table:
Name(0):
SID(0): S-1-1-0
IsGroup(0): False
Rights(0): FreeBusyAll
EntryId(0):
Name(1): UserA
SID(1): S-1-5-21-1234567890-1234567890-123456789-1681589
IsGroup(1): False
Rights(1): EditAny, DeleteAny, Author, FreeBusyAll
EntryId(1): 00000000 12345678 12345678 12345678 12345678 12345678 00000000 12345678 4D532F6F 753D4578 6368616E 67652041 646D696E 69737472 61746976 65204772 6F757020 28465944 49424F48 46323353 50444C54 292F636E 3D526563 69706965 6E74732F 636E3D4D 41594552 45303000
EntryId(1).Eidt: UserA
EntryId(1).EmailAddress: /o=G/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=UserA
Name(2): UserB
SID(2): S-1-5-21-1234567890-1234567890-123456789-1724373
IsGroup(2): False
Rights(2): ReadOnly, Visible
EntryId(2): 00000000 12345678 12345678 12345678 12345678 12345678 12345678 12345678 
EntryId(2).Eidt: UserB
EntryId(2).EmailAddress: /o=G/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=UserB
...
...
...

SID to Type map:
SID:S-1-1-0, Type:User
SID:S-1-5-21-1234567890-1234567890-123456789-1681589, Type:User
SID:S-1-5-21-1234567890-1234567890-123456789-1724373, Type:User
SID:S-1-5-21-1234567890-1234567890-123456789-1366337, Type:User
...
...
...

SD:
O:SYG:SYD:(A;CI;0x1208ab;;;S-1-5-21-1234567890-1234567890-123456789-1681589)(D;CI;0xd4114;;;S-1-5-21-1234567890-1234567890-123456789-1681589)(A;OIIO;0x1f0fbf;;;S-1-5-21-1234567890-1234567890-123456789-1681589)(A;CI;0x1208a9;;;S-1-5-21-1234567890-1234567890-123456789-1724373)(D;CI;0xd4116;;;S-1-5-21-1234567890-1234567890-123456789-1724373)(A;OIIO;0x1208a9;;;S-1-5-21-1234567890-1234567890-123456789-1724373)(D;OIIO;0xd0716;;;S-1-5-21-1234567890-1234567890-123456789-1724373)(A;CI;0x1208a9;;;S-1-5-21-1234567890-1234567890-123456789-1366337)(D;CI;0xd4116;;;S-1-5-21-1234567890-1234567890-123456789-1366337)(A;OIIO;0x1208a9;;;S-1-5-21-1234567890-1234567890-123456789-1366337)(D;OIIO;0xd0716;;;S-1-5-21-1234567890-1234567890-123456789-1366337)(A;CI;0x1208a9;;;S-1-5-21-1234567890-1234567890-123456789-1664815)(D;CI;0xd4116;;;S-1-5-21-1234567890-1234567890-123456789-1664815)(A;OIIO;0x1208a9;;;S-1-5-21-1234567890-1234567890-123456789-1664815) ... ... ...

FreeBusy SD: 
O:SYG:SYD:(A;CI;CCDC;;;S-1-5-21-1234567890-1234567890-123456789-1681589)(D;CI;CCDC;;;S-1-5-21-1234567890-1234567890-123456789-1724373)(D;CI;CCDC;;;S-1-5-21-1234567890-1234567890-123456789-1366337)(D;CI;CCDC;;;S-1-5-21-1234567890-1234567890-123456789-1664815)(D;CI;CCDC;;;S-1-5-21-1234567890-1234567890-123456789-1549750)(D;CI;CCDC;;;S-1-5-21-1234567890-1234567890-123456789-2149643)(D;CI;CCDC;;;S-1-5-21-1234567890-1234567890-123456789-1679850)(D;CI;CCDC;;;S-1-5-21-1234567890-1234567890-123456789-2181067)... ... ...

After observing raw FreeBusy SD, I noticed that all SIDs from the subject had "D" in front of ACE string which stands for "Deny":

 (D;CI;CCDC;;;S-1-5-21-1234567890-1234567890-123456789-1724373)
(D;CI;CCDC;;;S-1-5-21-1234567890-1234567890-123456789-1366337)

ACL string structure can be found here.

Raw ACL showed that FB permissions were incorrectly set on 'Calendar' folder, while Get-MailboxFolderPermission displayed folder level permission which were bit misleading. In order to correct this issue, user must set FB level permissions on 'Calendar' folder through Outlook and give the appropriate permission to the people that were experiencing the issue.