Thursday, April 2, 2009

MSCRM: Microsoft CRM Authentication Error 0x80040204

It's been a challenging afternoon today, following one of our clients introducing a new server to their network domain. Users trying to log into the Microsoft CRM system (hosted on another server) got the error: "Authentication Failed" with code 0x80040204.

The introduction of the new Microsoft Windows Server 2008 machine somehow affected the existing Microsoft Windows SBS 2003 domain controller, and changed (or recreated) the Active Directory groups which Microsoft CRM relies on: PrivUserGroup, ReportingGroup, SQLAccessGroup and UserGroup.

In the Application Event Log, errors were reported from the SCRMDeploymentManagerSnapin: "IsCRMSysAdmin : WhoAmI failed".

Checking the Microsoft CRM database, we could see that all System Users and Roles were still there, so the problem seemed to point towards Windows security and / or Active Directory.

We've found in the past that the best way to tackle these types of issue is to roll your sleeves up and get straight into the Microsoft CRM error tracing feature. Details of how to set this up are here: http://support.microsoft.com/kb/907490

Setting TraceCategories to "*:Verbose" will give you absolutely everything that's going on to understand the problem, but we strongly recommend only enabling this temporarily.

The Trace output file showed the SQL statements for the login; copy/pasting these into a query editor showed record being returned, so no problem there. the problem was found about 20 lines down in the Trace: "Invalid code for CRM error", "ADsGetObject() failed". Looking more and more like Active Directory.

Microsoft CRM relies on the PrivUserGroup, ReportingGroup, SQLAccessGroup and UserGroup Security Groups, so we checked the details of the GUIDs in Active Directory against those registered in the Microsoft CRM database.

Viewing the Microsoft CRM values can be done by running the following in a query editor:
SELECT UserGroupID , PrivilegeUserGroupID, ReportingGroupID, SQLAccessGroupID
FROM OrganisationBase

To view those in Active Directory, you'll need to use adsiedit.msc (part of the Windows Support Tools on the Windows Server installation CD-ROM or download it from http://download.microsoft.com, search for "adsiedit.msc") and view the objectGUID value for each of these groups in hex.

The values from Active Directory need to be manipulated slightly, but they should match those in the Microsoft CRM database: first reverse the first four groups of characters, reverse the next two groups of characters, reverse the third group of two and copy and paste the fourth group of two and the final group of six (the last two groups are not reversed). Note that you do not reverse each pair of characters individually, but treat each pair as a group and reverse the groups as shown below.

So, for example:
objectGUID=0x 1x 2x 3x 4x 5x 6x 7x 8x 9x Ax Bx Cx Dx Ex Fx

Becomes:
GUID in database={3x2x1x0x-5x4x-7x6x-8x9x-AxBxCxDxExFx}

The values we found didn't match, so it was just a simple SQL UPDATE statement to set them right:
UPDATE OrganizationBase
SET UserGroupID='GUID', PrivilegeUserGroupID='GUID', ReportingGroupID='GUID', SQLAccessGroupID='GUID'

Where 'GUID' is the appropriate manipulated Active Directory objectGUID.


As an example, the specific values we had in Active Directory for the four groups were:
A7 7D FB B8 8B 85 8C 47 81 F0 36 D6 F0 89 8A F7
CB F5 E6 71 58 B6 19 4A BA 56 CC 49 67 0C 58 FF
C5 CC DE B9 8A 72 DD 48 A6 4E 5E 4D D4 64 DD 0E
18 F7 97 EF 41 B9 C8 4E AA F8 3B 2D CE 02 EC A2


So manipulated as above they became:
B8FB7DA7-858B-478C-81F0-36D6F0898AF7
71E6F5CB-B658-4A19-BA56-CC49670C58FF
B9DECCC5-728A-48DD-A64E-5E4DD464DD0E
EF97F718-B941-4EC8-AAF8-3B2DCE02ECA2


Our SQL statement looked like this:
UPDATE OrganizationBase
SET UserGroupID = 'B8FB7DA7-858B-478C-81F0-36D6F0898AF7'
, PrivilegeUserGroupID = '71E6F5CB-B658-4A19-BA56-CC49670C58FF'
, ReportingGroupID = 'B9DECCC5-728A-48DD-A64E-5E4DD464DD0E'
, SQLAccessGroupID = 'EF97F718-B941-4EC8-AAF8-3B2DCE02ECA2'

Many thanks to Brian Reid for his blog post here - http://www.c7solutions.com/blog/2008/04/crm-30-disaster-recovery.aspx which was really helpful in getting us through this issue.