4

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);
                }
            }
        }
    }

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

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) 

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.

Mat
  • 202,337
  • 40
  • 393
  • 406
Yacoub Massad
  • 27,509
  • 2
  • 36
  • 62

1 Answers1

3

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.

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

e.g.:

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

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.

Yacoub Massad
  • 27,509
  • 2
  • 36
  • 62