C#, запрос терминального сервера Cassia и олицетворение
У меня есть функция, использующая библиотеку 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);
}
Выдача себя за другое лицо для меня в новинку, так что, возможно, у меня происходит фундаментальное недоразумение, а может, это просто проблема синтаксиса. Я не знаю. Любая помощь будет оценена