Saturday, January 19, 2013

Configuring a CRM Email Router to Run Under a Domain Service Account

If you tried running the CRM 2011 email router under a domain service account, you probably ran into some issues. Please, do not take the easy way out and make the account an administrator, you can give it the rights it needs without going to that extent.

The first thing it needs is the "log on as service" user right, but it should get that granted when you configure the service to run under your service account in services.msc. So, I'm going to assume that's already taken care of.


At this point, you are probably getting an error something like this:


Log Name:      Application
Source:        MSCRMEmail
Date:          1/15/2013 7:59:07 AM
Event ID:      16192
Task Category: None
Level:         Error
Keywords:      Classic
User:          N/A
Computer:      CrmServer.domain.com
Description:
#16192 - The E-mail Router service could not run the service main background thread. The E-mail Router service cannot continue and will now shut down. System.Configuration.ConfigurationErrorsException: System information was not specified in the E-mail Router service configuration file. The E-mail Router service cannot continue and will now shut down. ---> System.UnauthorizedAccessException: Access to the path 'D:\Program Files\Microsoft CRM Email\Service\Microsoft.Crm.Tools.EmailAgent.xml' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
   at System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
   at System.Xml.XmlTextReaderImpl.OpenUrlDelegate(Object xmlResolver)
   at System.Threading.CompressedStack.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.CompressedStack.Run(CompressedStack compressedStack, ContextCallback callback, Object state)
   at System.Xml.XmlTextReaderImpl.OpenUrl()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
   at System.Xml.XmlDocument.Load(XmlReader reader)
   at System.Xml.XmlDocument.Load(String filename)
   at Microsoft.Crm.Tools.Email.Providers.ConfigFileReader..ctor(String filePath, ServiceLogger serviceLogger)
   at Microsoft.Crm.Tools.Email.Providers.SystemConfiguration.Initialize(ServiceLogger serviceLogger)
   at Microsoft.Crm.Tools.Email.Agent.ServiceCore.InitializeSystemConfiguration()
   --- End of inner exception stack trace ---
   at Microsoft.Crm.Tools.Email.Agent.ServiceCore.InitializeSystemConfiguration()
   at Microsoft.Crm.Tools.Email.Agent.ServiceCore.ExecuteService()
Event Xml:

  
    
    16192
    2
    0
    0x80000000000000
    
    27722306
    Application
    CrmServer.domain.com
    
  
  
    #16192 - The E-mail Router service could not run the service main background thread. The E-mail Router service cannot continue and will now shut down. System.Configuration.ConfigurationErrorsException: System information was not specified in the E-mail Router service configuration file. The E-mail Router service cannot continue and will now shut down. ---> System.UnauthorizedAccessException: Access to the path 'D:\Program Files\Microsoft CRM Email\Service\Microsoft.Crm.Tools.EmailAgent.xml' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
   at System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
   at System.Xml.XmlTextReaderImpl.OpenUrlDelegate(Object xmlResolver)
   at System.Threading.CompressedStack.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.CompressedStack.Run(CompressedStack compressedStack, ContextCallback callback, Object state)
   at System.Xml.XmlTextReaderImpl.OpenUrl()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
   at System.Xml.XmlDocument.Load(XmlReader reader)
   at System.Xml.XmlDocument.Load(String filename)
   at Microsoft.Crm.Tools.Email.Providers.ConfigFileReader..ctor(String filePath, ServiceLogger serviceLogger)
   at Microsoft.Crm.Tools.Email.Providers.SystemConfiguration.Initialize(ServiceLogger serviceLogger)
   at Microsoft.Crm.Tools.Email.Agent.ServiceCore.InitializeSystemConfiguration()
   --- End of inner exception stack trace ---
   at Microsoft.Crm.Tools.Email.Agent.ServiceCore.InitializeSystemConfiguration()
   at Microsoft.Crm.Tools.Email.Agent.ServiceCore.ExecuteService()
  



Start by granting your service account read/execute rights to your email router service directory, which is something like D:\Program Files\Microsoft CRM Email\Service

Some of the files under this directory have broken security inheritance, so you will need to grant some more rights as well. Now, you need to grant your service account read/execute rights to the Microsoft.Crm.Tools.EmailAgent.xml file in that same email router service directory. After that you will probably get an error like this:


Log Name:      Application
Source:        MSCRMEmail
Date:          1/15/2013 8:02:37 AM
Event ID:      16192
Task Category: None
Level:         Error
Keywords:      Classic
User:          N/A
Computer:      CrmServer.domain.com
Description:
#16192 - The E-mail Router service could not run the service main background thread. The E-mail Router service cannot continue and will now shut down. System.UnauthorizedAccessException: Access to the path 'D:\Program Files\Microsoft CRM Email\Service\Microsoft.Crm.Tools.EmailAgent.SystemState.xml.bak' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite)
   at Microsoft.Crm.Tools.Email.Providers.ConfigFileReader.Backup()
   at Microsoft.Crm.Tools.Email.Agent.ServiceCore.UpdateConfiguration()
   at Microsoft.Crm.Tools.Email.Agent.ServiceCore.ScheduleProviderWork()
   at Microsoft.Crm.Tools.Email.Agent.ServiceCore.ExecuteService()
Event Xml:

  
    
    16192
    2
    0
    0x80000000000000
    
    27722309
    Application
    CrmServer.domain.com
    
  
  
    #16192 - The E-mail Router service could not run the service main background thread. The E-mail Router service cannot continue and will now shut down. System.UnauthorizedAccessException: Access to the path 'D:\Program Files\Microsoft CRM Email\Service\Microsoft.Crm.Tools.EmailAgent.SystemState.xml.bak' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite)
   at Microsoft.Crm.Tools.Email.Providers.ConfigFileReader.Backup()
   at Microsoft.Crm.Tools.Email.Agent.ServiceCore.UpdateConfiguration()
   at Microsoft.Crm.Tools.Email.Agent.ServiceCore.ScheduleProviderWork()
   at Microsoft.Crm.Tools.Email.Agent.ServiceCore.ExecuteService()
  



Now, you need to grant your service account full control rights to the Microsoft.Crm.Tools.EmailAgent.SystemState.xml.bak file in that CRM email router service directory. After which, you will probably get this error:


Log Name:      Application
Source:        MSCRMEmail
Date:          1/15/2013 8:06:19 AM
Event ID:      26234
Task Category: None
Level:         Error
Keywords:      Classic
User:          N/A
Computer:      CrmServer.domain.com
Description:
#26234 - The E-mail Router service could not process a provider work item using assembly: Microsoft.Crm.Tools.EmailProviders.dll and class: Microsoft.Crm.Tools.Email.Providers.ExchangePollingMailboxProvider. System.TypeInitializationException: The type initializer for 'Microsoft.Crm.Tools.Email.Providers.ProviderConfiguration' threw an exception. ---> System.UnauthorizedAccessException: Access to the path 'D:\Program Files\Microsoft CRM Email\Service\EncryptionKey.xml' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
   at System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
   at System.Xml.XmlTextReaderImpl.OpenUrlDelegate(Object xmlResolver)
   at System.Threading.CompressedStack.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.CompressedStack.Run(CompressedStack compressedStack, ContextCallback callback, Object state)
   at System.Xml.XmlTextReaderImpl.OpenUrl()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
   at System.Xml.XmlDocument.Load(XmlReader reader)
   at System.Xml.XmlDocument.Load(String filename)
   at Microsoft.Crm.Encryptor..ctor(String filePath)
   at Microsoft.Crm.Tools.Email.Providers.ProviderConfiguration..cctor()
   --- End of inner exception stack trace ---
   at Microsoft.Crm.Tools.Email.Providers.Utility.GetCrmService(ProviderConfiguration providerConfiguration)
   at Microsoft.Crm.Tools.Email.Providers.CrmPollingMailboxProvider.Run()
   at Microsoft.Crm.Tools.Email.Agent.ServiceCore.ExecuteProviderWork(Object providerQueueRequestObject)
Event Xml:

  
    
    26234
    2
    0
    0x80000000000000
    
    27722313
    Application
    CrmServer.domain.com
    
  
  
    #26234 - The E-mail Router service could not process a provider work item using assembly: Microsoft.Crm.Tools.EmailProviders.dll and class: Microsoft.Crm.Tools.Email.Providers.ExchangePollingMailboxProvider. System.TypeInitializationException: The type initializer for 'Microsoft.Crm.Tools.Email.Providers.ProviderConfiguration' threw an exception. ---> System.UnauthorizedAccessException: Access to the path 'D:\Program Files\Microsoft CRM Email\Service\EncryptionKey.xml' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
   at System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
   at System.Xml.XmlTextReaderImpl.OpenUrlDelegate(Object xmlResolver)
   at System.Threading.CompressedStack.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.CompressedStack.Run(CompressedStack compressedStack, ContextCallback callback, Object state)
   at System.Xml.XmlTextReaderImpl.OpenUrl()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
   at System.Xml.XmlDocument.Load(XmlReader reader)
   at System.Xml.XmlDocument.Load(String filename)
   at Microsoft.Crm.Encryptor..ctor(String filePath)
   at Microsoft.Crm.Tools.Email.Providers.ProviderConfiguration..cctor()
   --- End of inner exception stack trace ---
   at Microsoft.Crm.Tools.Email.Providers.Utility.GetCrmService(ProviderConfiguration providerConfiguration)
   at Microsoft.Crm.Tools.Email.Providers.CrmPollingMailboxProvider.Run()
   at Microsoft.Crm.Tools.Email.Agent.ServiceCore.ExecuteProviderWork(Object providerQueueRequestObject)
  



Now you need to grant your service account read/execute rights to the EncryptionKey.xml, which is in that same email router service directory. Then, it's on to the next error:


Log Name:      Application
Source:        MSCRMEmail
Date:          1/15/2013 8:34:40 AM
Event ID:      26234
Task Category: None
Level:         Error
Keywords:      Classic
User:          N/A
Computer:      CrmServer.domain.com
Description:
#26234 - The E-mail Router service could not process a provider work item using assembly: Microsoft.Crm.Tools.EmailProviders.dll and class: Microsoft.Crm.Tools.Email.Providers.ExchangePollingMailboxProvider. System.UnauthorizedAccessException: Access to the path 'D:\Program Files\Microsoft CRM Email\Service\Microsoft.Crm.Tools.EmailAgent.SystemState.xml' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
   at System.Xml.XmlDocument.Save(String filename)
   at Microsoft.Crm.Tools.Email.Providers.ConfigFileReader.Save()
   at Microsoft.Crm.Tools.Email.Providers.ConfigNodeReader.SetStringValue(String elementName, String setValue)
   at Microsoft.Crm.Tools.Email.Providers.PollingMailboxProvider.Run()
   at Microsoft.Crm.Tools.Email.Providers.CrmPollingMailboxProvider.Run()
   at Microsoft.Crm.Tools.Email.Agent.ServiceCore.ExecuteProviderWork(Object providerQueueRequestObject)
Event Xml:

  
    
    26234
    2
    0
    0x80000000000000
    
    27729613
    Application
    CrmServer.domain.com
    
  
  
    #26234 - The E-mail Router service could not process a provider work item using assembly: Microsoft.Crm.Tools.EmailProviders.dll and class: Microsoft.Crm.Tools.Email.Providers.ExchangePollingMailboxProvider. System.UnauthorizedAccessException: Access to the path 'D:\Program Files\Microsoft CRM Email\Service\Microsoft.Crm.Tools.EmailAgent.SystemState.xml' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
   at System.Xml.XmlDocument.Save(String filename)
   at Microsoft.Crm.Tools.Email.Providers.ConfigFileReader.Save()
   at Microsoft.Crm.Tools.Email.Providers.ConfigNodeReader.SetStringValue(String elementName, String setValue)
   at Microsoft.Crm.Tools.Email.Providers.PollingMailboxProvider.Run()
   at Microsoft.Crm.Tools.Email.Providers.CrmPollingMailboxProvider.Run()
   at Microsoft.Crm.Tools.Email.Agent.ServiceCore.ExecuteProviderWork(Object providerQueueRequestObject)
  



To fix this error, you need to grant your service account full control rights to the Microsoft.Crm.Tools.EmailAgent.SystemState.Xml file in that same email router service directoy. After that, it should work.

So, to wrap things up in one place, you need to grant the following files/folders the corresponding rights.

File/FolderPermissions
D:\Program Files\Microsoft CRM Email\Serviceread/execute
Microsoft.Crm.Tools.EmailAgent.xmlread/execute
Microsoft.Crm.Tools.EmailAgent.SystemState.xml.bakfull control
EncryptionKey.xmlread/execute
Microsoft.Crm.Tools.EmailAgent.SystemState.Xmlfull control