C#通过模拟访问的DirectoryEntry将引发灾难性的例外,第一次只灾难性、DirectoryEntry

2023-09-04 23:00:11 作者:戴上王冠就是女王

我使用的这个C#code冒充用户:

I am impersonating a user 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);
                }
            }
        }
    }

在哪里invocation_delegate将调用将访问Active Directory对象具有的DirectoryEntry(使用安全AuthenticationType)。该方法

Where invocation_delegate will call the method that will access Active Directory objects with DirectoryEntry (using Secure AuthenticationType).

我的问题是,我第一次调用的DirectoryEntry功能,它抛出以下异常:

My problem is that for the first time I invoke 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) 

如果我再访问使用相同的模拟环境或事件不同的模拟环境(撤消模拟,并再次冒充)的DirectoryEntry功能,则没有会抛出异常。

If I then access DirectoryEntry functions using the same impersonation context or event a different impersonation context (undo impersonation and impersonate again), then no exception will be thrown.

推荐答案

我认为,我发现这个问题。我有一个CLI / C ++ DLL。在我的C#项目的参考。如果我加载通过Assembly.LoadFile的DLL在节目的开始,那么这个问题就不会发生。如果在另一方面,我离开系统时,它认为合适的加载它(该系统似乎只加载它时,该DLL的实际调用完成),将发生异常。

I think that I found the problem. I have a CLI/C++ DLL as a reference in my C# project. If I load the DLL via Assembly.LoadFile at the start 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 call to the DLL is done), the the exception will occur.

我在打电话,我使用的DirectoryEntry功能的方法来此DLL中相同的方法。

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

例如:

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

无论如何,我认为这仍是需要修复的问题。即使该DLL稍后加载,应该没有例外。或者至少在调用的DirectoryEntry方法时,一定不要出现异常。

Anyway, I think this is still a problem that need to be fixed. Even if the DLL is loaded later, there should be no exception. Or at least the exception must not occur when calling the DirectoryEntry methods.