In part two of this blog series, we examine the role of technology in enhancing the customer experience in government with a focus on streamlining and automating customer-facing processes.
As a Microsoft Dynamics CRM administrator, you may run into issues where end-users do a certain action and receive an error message regarding permissions like the one below:
Access Is Denied
You do not have enough privileges to access the Microsoft Dynamics CRM object or preform the requested operation. For more information, contact your Microsoft Dynamics CRM administrator.
It tells them to contact you, so it's your lucky day. This message means that whatever action was being performed, the security role assigned to the user performing the action does not have adequate privileges. Now YOU need to determine what exactly the user does not have access to do.
Now you have three options:
1. Give the user the System Administrator role. This is not recommended, but it will give you a very quick fix.
2. Use your best judgment to determine what right are missing. Sometimes this is the best way. For example, if a user attempts to save a contact they don't own, and they have user-only write access to contacts, you may know right away what rights are missing without doing further trouble-shooting.
BUT if they are saving a type of record that has multiple relationships and lookups, this method would become increasingly inefficient. After a couple tries you might want to move to option 3.
3. Download the log file and determine the missing privilege.
When option #2 doesn't work and you just don't feel like playing whack-a-mole with security role privileges, your best option will be to read the log file and find out exactly what is missing. Don't worry - you don't have to be a coder or overly techy to read a log file! CRM does a very nice job of laying out what privilege is missing, by listing two key items: the entity type, and the rights type.
Let's start with a simple example. Imagine a user with the following security role:
As you can see, this user does not have the permissions to delete orders. If they try to do so, they will receive an "Access is Denied" message. If they click download log file, you will see the following:
-2147220970 System.Web.HttpUnhandledException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #C0133EE3 2014-07-28T13:52:14.9767207Z -2147187962 SecLib::AccessCheckEx failed. Returned hr = -2147187962, ObjectID: 8bd4de8b-5a16-e411-80c2-00155dcfd317, OwnerId: 15f85c02-6dd1-e311-80bb-00155dcfd318, OwnerIdType: 8 and CallingUser: 67fb54d8-6dd1-e311-80bb-00155dcfd318. ObjectTypeCode: 1088, objectBusinessUnitId: 1292bfc5-b0f9-e311-80c1-00155dcfd317, AccessRights: DeleteAccess 2014-07-28T13:52:14.9767207Z
Yikes! What is all that junk? Fortunately, it becomes easy to recognize and understand this with just a little additional info on what it all means. You only need to pay attention to two things from this entire message: the ObjectTypeCode, and the AccessRights. Let's take a closer look at that log file, and look at those two items again:
SecLib::AccessCheckEx failed. Returned hr = -2147187962, ObjectID: 8bd4de8b-5a16-e411-80c2-00155dcfd317, OwnerId: 15f85c02-6dd1-e311-80bb-00155dcfd318, OwnerIdType: 8 and CallingUser: 67fb54d8-6dd1-e311-80bb-00155dcfd318. ObjectTypeCode: 1088, objectBusinessUnitId: 1292bfc5-b0f9-e311-80c1-00155dcfd317, AccessRights: DeleteAccess 2014-07-28T13:52:14.9767207Z
The access rights should be self-evident: this message from CRM is saying the missing rights is Delete Access. But what about ObjectTypeCode? What does that even mean? How is 1088 going to help me?
Simply put, ObjectTypeCode is the numerical representation of a CRM entity or item. Fortunately, Microsoft has a listing of all ObjectTypeCodes that come with CRM. If you do a search in this page for "1088", you will see that it refers to "SalesOrder," which is the Order entity.
Therefore, the log file that we downloaded contains the information that the user is missing Delete rights (AccessRights: DeleteAccess) for the Order entity (ObjectTypeCode 1088).
So now let's try a more complicated example, using custom entities.
I have a user that reported an error creating this record:
I then asked him for the log file, and he sent me this:
Unhandled Exception: System.ServiceModel.FaultException1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=188.8.131.52, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: SecLib::AccessCheckEx failed. Returned hr = -2147187962, ObjectID: f2188e1a-85a1-e411-9423-00155dcfc00d, OwnerId: 60b7716d-b866-e411-941d-00155dcfc126, OwnerIdType: 8 and CallingUser: ca8f4a13-8ca1-e411-9423-00155dcfc00d. ObjectTypeCode: 10085, objectBusinessUnitId: 41f74f5e-b666-e411-941d-00155dcfc126, AccessRights: AppendToAccess Detail:
-2147187962 CallStack at Microsoft.Crm.Extensibility.VersionedPluginProxyStepBase.Execute(PipelineExecutionContext context) at Microsoft.Crm.Extensibility.Pipeline.Execute(PipelineExecutionContext context) at Microsoft.Crm.Extensibility.MessageProcessor.Execute(PipelineExecutionContext context) at Microsoft.Crm.Extensibility.InternalMessageDispatcher.Execute(PipelineExecutionContext context) at Microsoft.Crm.Extensibility.ExternalMessageDispatcher.ExecuteInternal(IInProcessOrganizationServiceFactory serviceFactory, IPlatformMessageDispatcherFactory dispatcherFactory, String messageName, String requestName, Int32 primaryObjectTypeCode, Int32 secondaryObjectTypeCode, ParameterCollection fields, CorrelationToken correlationToken, CallerOriginToken originToken, UserAuth userAuth, Guid callerId, Guid transactionContextId, Int32 invocationSource, Nullable1 requestId, Version endpointVersion) at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, UserAuth userAuth, Guid targetUserId, OrganizationContext context, Boolean returnResponse, Boolean checkAdminMode) at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.ExecuteRequest(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, Boolean checkAdminMode) at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.Execute(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, Boolean checkAdminMode) SecLib::AccessCheckEx failed. Returned hr = -2147187962, ObjectID: f2188e1a-85a1-e411-9423-00155dcfc00d, OwnerId: 60b7716d-b866-e411-941d-00155dcfc126, OwnerIdType: 8 and CallingUser: ca8f4a13-8ca1-e411-9423-00155dcfc00d. ObjectTypeCode: 10085, objectBusinessUnitId: 41f74f5e-b666-e411-941d-00155dcfc126, AccessRights: AppendToAccess 2015-01-26T16:11:49.9974893Z
While it contains a lot of information, again, keep in mind we are only concerned with the AccessRights and ObjectTypeCode. Looking at the above log file, we gather the following:
Therefore, we are missing Append to rights for the entity that corresponds to ObjectTypeCode 10085. Unfortunately, we can't use the link above from Microsoft that provides default entity type codes. Fortunately, there is an extremely easy way to find the ObjectTypeCode for any entity including custom ones without the need to access the database directly or write code. Simply navigate to the following URL:
Where etc=10085 is taken from the error log. So if your error message gave ObjectTypeCode = 10120, then the URL you would go to would be /main.aspx?etc=10120&pagetype=entityrecord
But let's go back to the example above. If I were to go to that URL as shown above, I would see the following page:
This means that ObjectTypeCode of 10085 is the Olives entity! And since the message also mentioned we are missing Append to rights, we can conclude that the missing privilege is Append To rights for Olives.
We hope this helps all you Dynamics CRM admins out there! For more on topics related to this blog, we have compiled a list of similar blogs: