0

我在表单应用程序中有一个使用 Cassia 库的函数,该函数将所有通过 rdp 登录的用户返回到会话主机以及有关其会话的一些详细信息(然后将其添加到 datagridview)。

只要您在域中,它就可以正常工作。

但是我想在域外运行这个函数。模拟似乎是可行的方法,但我遇到了问题,我要么得到“错误的用户名或密码”(当我 100% 确定它们是正确的),要么得到一个“访问被拒绝”错误从决明子函数。这意味着模拟没有引发错误,但它也没有工作。

我看到一些地方提到必须在您连接的机器上将注册表代码 AllowRemoteRPC 设置为 1,这已经是这种情况了。

代码(主要是从其他地方复制的):

string serverAddr = "server.com";
string userName = "domainUser"
string uPw = "1234"

IntPtr token;
if (!NativeMethods.LogonUser(userName, serverAddr, uPw, NativeMethods.LogonType.NewCredentials, NativeMethods.LogonProvider.WinNT50, out token))
{
   throw new Win32Exception();
}
try
{
   IntPtr tokenDuplicate;

    if (!NativeMethods.DuplicateToken(token, NativeMethods.SecurityImpersonationLevel.Impersonation, out tokenDuplicate))
    {
        throw new Win32Exception();
    }

    try
    {
         using (WindowsImpersonationContext impersonationContext = new WindowsIdentity(tokenDuplicate).Impersonate())
         {
             #Do stuff here querying the terminal servers
              ITerminalServicesManager manager = new TerminalServicesManager();
                    
              IList<ITerminalServer> svs = manager.GetServers("DOMAIN"); 

              int rowCnt = 0;

              foreach (ITerminalServer server in svs)
              {

                  server.Open();
                  string svr = default(string);
                  string cName = default(string);
                  string state = default(string);
                  string uName = default(string);

                  foreach (ITerminalServicesSession session in server.GetSessions())
                  {
                      NTAccount account = session.UserAccount;
                      uName = session.UserName;
                      svr = session.Server.ServerName;
                      cName = session.ClientName;
                      state = session.ConnectionState.ToString();

                      if (account != null)
                      {
                          userGrid1.Rows.Add();
                          userGrid1.Rows[rowCnt].Cells[0].Value = uName;
                          userGrid1.Rows[rowCnt].Cells[1].Value = svr;
                          userGrid1.Rows[rowCnt].Cells[2].Value = cName;
                          userGrid1.Rows[rowCnt].Cells[3].Value = state;

                          rowCnt++;
                      }

                 }

             }   

             impersonationContext.Undo();
         }
     }
     finally
     {
          if (tokenDuplicate != IntPtr.Zero)
          {
               NativeMethods.CloseHandle(tokenDuplicate);
          }
     }
  }
  finally
  {
       if (token != IntPtr.Zero)
       {
          NativeMethods.CloseHandle(token);
       }
 }
        
}

#the above is all inside a function, NativeMethods class copied below for clarity;

    internal static class NativeMethods
    {
        internal enum LogonType : int
        {
            Interactive = 2,
            Network = 3,
            Batch = 4,
            Service = 5,
            Unlock = 7,
            NetworkCleartext = 8,
            NewCredentials = 9
        }

        internal enum LogonProvider : int
        {
            Default = 0,
            WinNT35 = 1,
            WinNT40 = 2,
            WinNT50 = 3
        }

        internal enum SecurityImpersonationLevel : int
        {

            Anonymous = 0,
            Identification = 1,
            Impersonation = 2,
            Delegation = 3
        }

        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool LogonUser(
            string userName,
            string domain,
            string password,
            LogonType logonType,
            LogonProvider logonProvider,
            out IntPtr token);

        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool DuplicateToken(
            IntPtr existingTokenHandle,
            SecurityImpersonationLevel securityImpersonationLevel,
            out IntPtr duplicateTokenHandle);

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool CloseHandle(IntPtr handle);
    }

模拟对我来说很新,所以我可能有一个基本的误解,或者它只是一个语法问题。我不知道。任何帮助,将不胜感激

4

0 回答 0