У меня есть приложение, которое выполняется службой. Приложение настроено таким образом, что оно работает только под одной учетной записью пользователя Windows, то есть с пользователем, который установил программное обеспечение. Способ, которым это выполняется, во время установки, приложение сохраняет комбинацию имени пользователя/домена пользователя, который инициировал установку, а затем службу, в зависимости от того, активен ли пользовательский сеанс, решает ли запустить приложение.WTSQuerySessionInformation возвращает другое доменное имя
Один из наших клиентов сообщил, что приложение не работает в его учетной записи, и после дальнейшего расследования мы обнаружили, что по какой-либо причине при запросе информации о сеансе возвращаемое имя домена отличается для одного и того же идентификатора сеанса.
Это PInvoke для WTSQuerySessionInformation:
[DllImport("Wtsapi32.dll", SetLastError = true)]
static extern bool WTSQuerySessionInformation(
IntPtr hServer,
uint sessionId,
WTS_INFO_CLASS wtsInfoClass,
out IntPtr ppBuffer,
out uint pBytesReturned
);
и это, как мы получаем проверки службы, если пользователь имеет активный сеанс:
WTSEnumerateSessions(IntPtr.Zero, 0, 1, ref pSessionInfo, ref dwCount);
Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
Int32 current = (int)pSessionInfo;
uint bytes = 0;
for (int i = 0; i < dwCount; i++)
{
WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO));
if (WTS_CONNECTSTATE_CLASS.WTSActive == si.State)
{
IntPtr userPtr = IntPtr.Zero;
IntPtr domainPtr = IntPtr.Zero;
//Check if the active session matches the saved username/domain
WTSQuerySessionInformation(IntPtr.Zero, (uint)si.SessionID, WTS_INFO_CLASS.WTSUserName, out userPtr, out bytes);
WTSQuerySessionInformation(IntPtr.Zero, (uint)si.SessionID, WTS_INFO_CLASS.WTSDomainName, out domainPtr, out bytes);
string sessionUName = Marshal.PtrToStringAnsi(userPtr);
string sessionDomain = Marshal.PtrToStringAnsi(domainPtr);
}
}
Проблема, когда служба детектирует пользовательский сеанс и пытается получить доменное имя, возвращаемое имя отличается от фактического имени домена пользователя, даже если идентификатор сеанса правильный для этого конкретного пользователя.
Если это помогает доменному имени, возвращенному с WTSQuerySessionInformation
, является NTLAN_1
, который полностью отличается от фактического домена пользователя.
Я хотел бы знать, есть ли что-то неправильное с pInvoke WTSQuerySessionInformation
или любым вызовом в вышеуказанном коде. Также хотел бы знать, связан ли домен NTLAN_1
с каким-либо сервисом или приложением RDP любого типа.
EDIT:
После долгих переговоров мне удалось получить результат для LsaEnumerateLogonSessions
и LsaGetLogonSessionData
, к сожалению, это тот же самый результат, и ни один из перечисленных сессий не имеет ожидаемый доменное имя. Вот список сессий с их уважаемой информацию от LsaEnumerateLogonSessions
:
Session: 0 User: MARK *** Domain: NTLAN_1 *** Login Type: (3) Network *** Login Time: 2/6/2014 7:34:17 AM
Session: 0 User: ADMINISTRATOR *** Domain: NTLAN_1 *** Login Type: (3) Network *** Login Time: 2/4/2014 7:47:11 AM
Session: 0 User: ADMINISTRATOR *** Domain: NTLAN_1 *** Login Type: (3) Network *** Login Time: 1/27/2014 3:27:33 PM
Session: 0 User: MCMFILE2$ *** Domain: NTLAN_1 *** Login Type: (5) Service *** Login Time: 1/16/2014 3:52:46 PM
Session: 0 User: MCM-LR9-YE91K$ *** Domain: NTLAN_1 *** Login Type: (3) Network *** Login Time: 2/6/2014 10:52:40 AM
Session: 0 User: MARK *** Domain: NTLAN_1 *** Login Type: (3) Network *** Login Time: 2/6/2014 10:19:39 AM
Session: 0 User: ADMINISTRATOR *** Domain: NTLAN_1 *** Login Type: (3) Network *** Login Time: 1/20/2014 9:57:57 AM
Session: 0 User: ANONYMOUS LOGON *** Domain: NT AUTHORITY *** Login Type: (3) Network *** Login Time: 1/16/2014 3:53:19 PM
Session: 1 User: ADMINISTRATOR *** Domain: NTLAN_1 *** Login Type: (2) Interactive *** Login Time: 1/16/2014 3:53:11 PM
Session: 0 User: LOCAL SERVICE *** Domain: NT AUTHORITY *** Login Type: (5) Service *** Login Time: 1/16/2014 3:52:46 PM
Session: 0 User: MARK *** Domain: NTLAN_1 *** Login Type: (3) Network *** Login Time: 2/6/2014 10:52:40 AM
Session: 1 User: ADMINISTRATOR *** Domain: NTLAN_1 *** Login Type: (3) Network *** Login Time: 2/6/2014 10:52:38 AM
Session: 0 User: MARK *** Domain: NTLAN_1 *** Login Type: (3) Network *** Login Time: 2/6/2014 10:19:39 AM
Session: 0 User: ADMINISTRATOR *** Domain: NTLAN_1 *** Login Type: (3) Network *** Login Time: 1/18/2014 6:20:25 PM
Session: 0 User: ANONYMOUS LOGON *** Domain: NT AUTHORITY *** Login Type: (3) Network *** Login Time: 1/16/2014 3:53:19 PM
Session: 0 User: CVSMANAGER_USER *** Domain: MCMFILE2 *** Login Type: (5) Service *** Login Time: 1/16/2014 3:53:09 PM
Session: 0 User: MCM-LR9-YE91K$ *** Domain: NTLAN_1 *** Login Type: (3) Network *** Login Time: 2/6/2014 10:52:40 AM
Session: 0 User: MARK *** Domain: NTLAN_1 *** Login Type: (3) Network *** Login Time: 2/6/2014 10:19:39 AM
Session: 0 User: DefaultAppPool *** Domain: IIS APPPOOL *** Login Type: (5) Service *** Login Time: 2/6/2014 8:42:47 AM
Session: 0 User: ADMINISTRATOR *** Domain: NTLAN_1 *** Login Type: (3) Network *** Login Time: 2/4/2014 2:40:40 PM
Session: 0 User: IUSR *** Domain: NT AUTHORITY *** Login Type: (5) Service *** Login Time: 1/16/2014 3:53:09 PM
Session: 0 User: MCMFILE2$ *** Domain: NTLAN_1 *** Login Type: (0) 0 *** Login Time: 1/16/2014 3:52:44 PM
Сеанс в вопросе есть идентификатор сеанса = 1. А из списка он показывает имя домена быть NTLAN_1 вместо фактического домена.
Теперь я заметил что-то странное в своем настольном приложении, которое, я считаю, имеет решающее значение для поиска решения этой проблемы, но я не уверен, что с этим делать.
Теперь мое настольное приложение написано на .NET, поэтому я попытался получить имя пользователя и домен, запустив приложение напрямую. Теперь самое смешное, если я использую встроенную функцию GetUserNameEx
и передаю NameUserPrincipal
в качестве NameFormat, я могу получить правильную комбинацию имени пользователя/домена. Однако, и это забавная часть, когда я пытаюсь получить доменное имя, используя класс Environment
, позвонив по телефону Environment.UserDomainName
. Я получаю преступника NTLAN_1. обратите внимание, что как управляемые, так и неуправляемые вызовы выполнялись одним и тем же приложением в одном и том же режиме.
У меня раньше не было такой проблемы, и теперь у меня есть еще несколько пользователей, которые сообщили о той же проблеме, и это начало меня беспокоить.
Интересно, является ли пользователь «олицетворением»? –
Если вы можете добавить диагностический код в свою службу и запустить его на рассматриваемой машине, вы можете попробовать использовать 'WTSQueryUserToken', чтобы получить токен и распаковать его, чтобы узнать, есть ли что-то странное в части домена SID. Вы также можете посмотреть на «TokenSource», «TokenSessionId» и «TokenOrigin» (см. «LsaGetLogonSessionData'), чтобы увидеть, что там происходит что-то странное. –
@HarryJohnston К сожалению, я не могу проверить что-либо на рассматриваемой машине. Но хотелось бы знать, в чем преимущество получения такой информации в моем случае. –