【问题标题】:Unable to find an entry point named 'LogonUser' in DLL 'advapi32.dll' Impersonation exception无法在 DLL“advapi32.dll”模拟异常中找到名为“LogonUser”的入口点
【发布时间】:2011-10-17 07:32:37
【问题描述】:

在处理一些遗留模拟逻辑时,我遇到了以下异常:

无法在 DLL 'advapi32.dll' 中找到名为 'LogonUser' 的入口点

我了解该错误意味着我的应用在 advapi32.dll 中找不到 LogonUser 方法。

代码如下所示:

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
private static extern bool LogonUser(String lpszUsername, String lpszDomain, String     lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);



if(LogonUser(_username, _domainname, _password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref _tokenHandle))
{
//do stuff...
}

有没有人遇到过类似的错误 - 关于如何修复它或为什么会发生的任何建议?除了使用 advapi32.dll(它是一个 .net 3.5 解决方案,但有很多遗留类)之外,还有更好的方法吗?

【问题讨论】:

    标签: c# asp.net impersonation


    【解决方案1】:

    也许它与“ExactSpelling = true”有关

    这似乎有效:

    public enum LogonType : int
    {
        Interactive = 2,
        Network = 3,
        Batch = 4,
        Service = 5,
        Unlock = 7,
        NetworkCleartText = 8,
        NewCredentials = 9,
    }
    
    public enum LogonProvider : int
    {  
        Default = 0,
    }
    
    public class Impersonation : IDisposable
    {
        #region Dll Imports
    
        [DllImport("kernel32.dll")]
        private static extern Boolean CloseHandle(IntPtr hObject);
    
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool LogonUser(string username, string domain,
                                              string password, LogonType logonType,
                                              LogonProvider logonProvider,
                                              out IntPtr userToken);
    
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool DuplicateToken(IntPtr token, int impersonationLevel,
            ref IntPtr duplication);
    
              [DllImport("advapi32.dll", SetLastError = true)]
        static extern bool ImpersonateLoggedOnUser(IntPtr userToken);
        #endregion
    
        #region Private members
    
        private bool _disposed;
    
        private WindowsImpersonationContext _impersonationContext;
    
        #endregion
    
        #region Constructors
    
        public Impersonation(String username, String domain, String password)
        {
            IntPtr userToken = IntPtr.Zero;
            IntPtr userTokenDuplication = IntPtr.Zero;
    
            // Logon with user and get token.
            bool loggedOn = LogonUser(username, domain, password,
                LogonType.Interactive, LogonProvider.Default,
                out userToken);
    
            if (loggedOn)
            {
                try
                {
                    // Create a duplication of the usertoken, this is a solution
                    // for the known bug that is published under KB article Q319615.
                    if (DuplicateToken(userToken, 2, ref userTokenDuplication))
                    {
                        // Create windows identity from the token and impersonate the user.
                        WindowsIdentity identity = new WindowsIdentity(userTokenDuplication);
                        _impersonationContext = identity.Impersonate();
                    }
                    else
                    {
                        // Token duplication failed!
                        // Use the default ctor overload
                        // that will use Mashal.GetLastWin32Error();
                        // to create the exceptions details.
                        throw new Exception("Could not copy token");
                    }
                }
                finally
                {
                    // Close usertoken handle duplication when created.
                    if (!userTokenDuplication.Equals(IntPtr.Zero))
                    {
                        // Closes the handle of the user.
                        CloseHandle(userTokenDuplication);
                        userTokenDuplication = IntPtr.Zero;
                    }
    
                    // Close usertoken handle when created.
                    if (!userToken.Equals(IntPtr.Zero))
                    {
                        // Closes the handle of the user.
                        CloseHandle(userToken);
                        userToken = IntPtr.Zero;
                    }
                }
            }
            else
            {               
                throw new Exception("Login failed");
            }
        }
    
        ~Impersonation()
        {
            Dispose(false);
        }
        #endregion
    
        #region Public methods
    
        public void Revert()
        {
            if (_impersonationContext != null)
            {
                // Revert to previous user.
                _impersonationContext.Undo();
                _impersonationContext = null;
            }
        }
        #endregion
    
        #region IDisposable implementation.
    
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                Revert();
    
                _disposed = true;
            }
        }
        #endregion
    }
    

    【讨论】:

    • 看起来这可能是原因,因为这是我的示例和 pinvoke.net 上的示例之间的唯一区别 - 一有机会就进行不良测试
    【解决方案2】:

    您是否尝试过使用pinvoke.net 上提供的LogonUser 签名版本?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-14
      • 1970-01-01
      • 2021-08-05
      • 2017-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多