Monday, June 29, 2015

Principal user is missing prvReadComplexControl privilege

Recently we have upgraded CRM 2011 to CRM 2013 and we were getting generic errors "Insufficient permissions" when we open few entity forms in CRM

On debugging after switching on CRM trace logs we have found that the user is missing some privilages. Below is the execption we got.

>UNEXPECTED: no fault?
[2015-06-29 01:21:28.151] Process: w3wp |Organization:00000000-0000-0000-0000-000000000000 |Thread:  346 |Category: Platform |User: 00000000-0000-0000-0000-000000000000 |Level: Error |ReqId: 33a6e86d-6e32-48b9-8065-d3aa8f576c42 | ExceptionConverter.ConvertMessageAndErrorCode  ilOffset = 0x23B
>System.Web.HttpException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #41EB8FD7: System.Web.HttpException (0x80004005): Error executing child request for /CRMUPGV5/_forms/read/page.aspx. ---> System.Web.HttpUnhandledException (0x80004005): Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> Microsoft.Crm.CrmException: Principal user (Id=40f2886d-c8da-e111-80f0-005056ae010b, type=8) is missing prvReadComplexControl privilege (Id=a4736385-9763-4a64-a44b-cd5933edc631)
>   at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal()
>   at Microsoft.Crm.Application.Platform.ServiceCommands.RetrieveCommand.Execute()
>   at Microsoft.Crm.Caching.ComplexControlLoader.LoadCacheData(Guid key, IOrganizationContext context)
>   at Microsoft.Crm.Caching.CrmMultiOrgCacheBase`2.CreateEntry(TKey key, IOrganizationContext context)
>   at Microsoft.Crm.Caching.CrmMultiOrgCacheBase`2.LookupEntry(TKey key, IOrganizationContext context)
>   at Microsoft.Crm.Application.Components.Sdk.InlineEditControls.Web.CompositionLinkControl.GetFlyOutDescriptor()
>   at Microsoft.Crm.Application.Components.Sdk.InlineEditControls.Web.LinkControl.GetRequiredColumns(Int32 entityTypeCode)
>   at Microsoft.Crm.Application.Forms.CompositeControlVisitor.HandleColumnProvider(Control control, FormDescriptor formDescriptor)
>   at Microsoft.Crm.Application.InlineEdit.Mediators.FormMediator.AddControlProperties(ICrmControl crmControl, ControlDescriptor controlDescriptor)
>   at Microsoft.Crm.Application.InlineEdit.Mediators.FormMediator.ProcessControlHierarchy(Action`2 controlHandler)
>   at Microsoft.Crm.Application.InlineEdit.Mediators.FormMediator.GetInstance(FormFactor formFactor, FormDescriptor descriptor, Guid processId, Int64 processVersionNumber, IOrganizationContext organizationContext)
>   at Microsoft.Crm.Application.InlineEdit.Mediators.FormMediator.GetInstance(FormFactor formFactor, Guid formId, Guid processId, Int64 processVersionNumber, IOrganizationContext organizationContext)
>   at Microsoft.Crm.Application.InlineEdit.ReadFormDataBuilder..ctor(String recordId, String entityTypeCode, Guid formId, FormFactor formFactor)
>   at Microsoft.Crm.Application.Pages.Common.ReadFormPage.PopulateFormDescriptorAndDataBuilder()
>   at Microsoft.Crm.Application.Pages.Common.ReadFormPage.OnPreInit()
>   at Microsoft.Crm.Application.Controls.AppUIPage.OnInit(EventArgs e)
>   at Microsoft.Crm.Application.Controls.AppPage.OnInit(EventArgs e)
>   at System.Web.UI.Control.InitRecursive(Control namingContainer)
>   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
>   at System.Web.UI.Page.HandleError(Exception e)
>   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
>   at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
>   at System.Web.UI.Page.ProcessRequest()
>   at System.Web.UI.Page.ProcessRequest(HttpContext context)
>   at System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride)
>   at System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride)
>   at System.Web.HttpServerUtility.Execute(String path, TextWriter writer, Boolean preserveForm)
>   at System.Web.HttpServerUtility.Transfer(String path)
>   at System.Web.UI.Control.PreRenderRecursiveInternal()
>   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
>   at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
>   at System.Web.UI.Page.ProcessRequest()
>   at System.Web.UI.Page.ProcessRequest(HttpContext context)
>   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
>   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)



The error seems to talk about some complex control in CRM to which the user does not have read privilege. Perplexed that you never heard of any ComplexControl entity in CRM?

However a little bit of search in SDK regarding this privilege and this is what I got from the SDK.
ComplexControl entity is for internal use only. However, users need read access to this entity in order to see the updated experience for lead and opportunity forms.
Still can’t find the complexcontrol entity? No worries. Open the security roles of the user who is getting this error.
Go to Customizations tab and search for the Process Configuration entity and assign the privileges for the security role. Check the below screenshot.




The SDK also clearly states out that this privilege is for Process Configuration entity.


Hope this helps someone who face similar problems!!!