C # accessing DirectoryEntry through impersonation will cause a catastrophic exception for the first time

I am using this C # code:

SafeTokenHandle logon_token = null; SafeTokenHandle duplicate_token = null; const int LOGON32_PROVIDER_DEFAULT = 0; const int LOGON32_LOGON_INTERACTIVE = 2; const int SecurityImpersonation = 2; if (!LogonUser(m_Username, m_Domain, m_Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,out logon_token)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } using (logon_token) { if (!DuplicateToken(logon_token, SecurityImpersonation, out duplicate_token)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } using (duplicate_token) { using (WindowsIdentity new_id = new WindowsIdentity(logon_token.DangerousGetHandle())) { using (WindowsImpersonationContext impersonatedUser = new_id.Impersonate()) { return invocation_delegate(param); } } } } 

If invocation_delegate calls a method that will access Active Directory objects using DirectoryEntry (using Secure AuthenticationType).

My problem is that the first time I call DirectoryEntry functionality, it throws the following exception:

 Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED)) at System.Security.Policy.PEFileEvidenceFactory.GetLocationEvidence(SafePEFileHandle peFile, SecurityZone& zone, StringHandleOnStack retUrl) at System.Security.Policy.PEFileEvidenceFactory.GenerateLocationEvidence() at System.Security.Policy.PEFileEvidenceFactory.GenerateEvidence(Type evidenceType) at System.Security.Policy.AssemblyEvidenceFactory.GenerateEvidence(Type evidenceType) at System.Security.Policy.Evidence.GenerateHostEvidence(Type type, Boolean hostCanGenerate) at System.Security.Policy.Evidence.GetHostEvidenceNoLock(Type type) at System.Security.Policy.Evidence.GetHostEvidence(Type type, Boolean markDelayEvaluatedEvidenceUsed) at System.Security.Policy.AppDomainEvidenceFactory.GenerateEvidence(Type evidenceType) at System.Security.Policy.Evidence.GenerateHostEvidence(Type type, Boolean hostCanGenerate) at System.Security.Policy.Evidence.GetHostEvidenceNoLock(Type type) at System.Security.Policy.Evidence.RawEvidenceEnumerator.MoveNext() at System.Security.Policy.Evidence.EvidenceEnumerator.MoveNext() at System.Configuration.ClientConfigPaths.GetEvidenceInfo(AppDomain appDomain, String exePath, String& typeName) at System.Configuration.ClientConfigPaths.GetTypeAndHashSuffix(AppDomain appDomain, String exePath) at System.Configuration.ClientConfigPaths..ctor(String exePath, Boolean includeUserConfig) at System.Configuration.ClientConfigPaths.GetPaths(String exePath, Boolean includeUserConfig) at System.Configuration.ClientConfigurationHost.RequireCompleteInit(IInternalConfigRecord record) at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) at System.Configuration.BaseConfigurationRecord.GetSection(String configKey) at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName) at System.Configuration.ConfigurationManager.GetSection(String sectionName) at System.Configuration.PrivilegedConfigurationManager.GetSection(String sectionName) at System.DirectoryServices.SearchResultCollection.ResultsEnumerator..ctor(SearchResultCollection results, String parentUserName, String parentPassword, AuthenticationTypes parentAuthenticationType) at System.DirectoryServices.SearchResultCollection.GetEnumerator() at System.DirectoryServices.DirectorySearcher.FindOne() at Utilities.ADUtilities.GetEnrollmentServiceByNameAndDNSName(String name, String dns_name) 

If I then access DirectoryEntry functions using the same context or an impersonation event of a different impersonation context (cancel the impersonation and impersonate another), then the exception will not be thrown.

+4
source share
1 answer

I think I found the problem. I have a CLI / C ++ DLL as a reference in my C # project. If I load the DLL through Assembly.LoadFile at the beginning of the program, then the problem will not happen. If, on the other hand, I leave the system to load it when it sees fit (the system seems to load it only when the actual DLL call is made), an exception will occur.

I call methods for this DLL in the same method in which I use DirectoryEntry functions.

eg:.

 void Method1() { DirectoryEntry de = //.... de. //.... CLICPPLibrary.DoStuff(); } 

In any case, I think this is still a problem that needs to be fixed. Even if the DLL loads later, there should be no exceptions. Or, at least, an exception should not occur when calling DirectoryEntry methods.

+3
source

All Articles