使用LOGON32_LOGON_NEW_CREDENTIALS模拟Windows有什么魔力

本文关键字:Windows 什么 模拟 魔力 CREDENTIALS LOGON32 LOGON NEW 使用 | 更新日期: 2023-09-27 18:26:43

根据我在Windows上对用户模拟的阅读,应该正确使用LOGON32_LOGON_NEW_CREDENTIALS登录类型来模拟数据库中的用户。使用Matt Johnson漂亮的模拟包装器(最初发布在这里,然后在这里完善),我试图测试这一点——这是我的整个程序,除了定义我的特定DOMAIN、USER、PWD和CONN_STRING的常量。

using System;
using System.Data.SqlClient;
using SimpleImpersonation;
namespace ImpersonationDemo
{
    class Program
    {
        private static SqlConnection _connection;
        static void Main(string[] args)
        {
            using (Impersonation.LogonUser(
                    DOMAIN, USER, PWD, LogonType.NewCredentials))
            {
                GetOpenConnection();
                CheckDbCredentials();
                CloseConnection();
            }
            Console.WriteLine("Press return to exit");
            Console.ReadLine();
        }
        private static void CheckDbCredentials()
        {
            using (
                var command = new SqlCommand(
                    "SELECT nt_user_name, SUSER_SNAME() "
                    +"FROM sys.dm_exec_sessions WHERE session_id = @@SPID",
                    _connection))
            {
                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        Console.WriteLine("{0}, {1}",
                            reader.GetString(0), reader.GetString(1));
                    }
                }
            }
        }

        private static void GetOpenConnection()
        {
            _connection = new SqlConnection(CONN_STRING);
            _connection.Open();
        }
        private static void CloseConnection()
        {
            _connection.Close();
        }
    }
}

但这行不通输出报告来自nt_user_nameSUSER_NAME()me(我的基本登录用户)。(SQL事件探查器报告的内容完全相同;代码中的查询只是查看SQL事件探查程序告诉我的内容的一种方便方式。)

如果我从LogonType.NewCredentials更改为LogonType.Interactive(这些枚举具有您期望的值,如在pinvoke.net上定义的),那么它确实有效——上面的代码报告了正确的DOMAIN和USER模拟。但这也意味着当前会话正在被模拟,这是我不希望的——我只希望模拟DB连接。

我想我在上面发现了一个小故障——Johnson的模拟包装器将登录提供程序硬编码为LOGON32_PROVIDER_DEFAULT,而LogoUser API明确表示LOGON32_LOGON_NEW_CREDENTIALS登录类型仅受LOGON32_PROVIDER_WINNT50登录提供程序支持。因此,我获取了源并添加了一个参数,以允许指定必需的登录提供程序。。。但这并没有什么区别。

那么我错过了什么?

使用LOGON32_LOGON_NEW_CREDENTIALS模拟Windows有什么魔力

我很惭愧地说,答案一直就在我面前。LogoUserneneneba API声明:

此登录类型允许调用方克隆其当前令牌,并为出站连接指定新凭据。新登录会话具有相同的本地标识符,但对其他网络连接使用不同的凭据[强调矿]

但是我的数据库和我正在运行的程序在同一台机器上,所以根据定义,它不会显示新的凭据!我相信,一旦我将数据库移动到另一个框中,模拟将正确使用LOGON32_LOGON_NEW_CREDENTIALS<叹气>