Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.12.26;
Скачать: CL | DM;

Вниз

проблемка с LsaGetLogonSessionData...   Найти похожие ветки 

 
istok   (2010-09-27 23:40) [0]

нижеприведенная программка является демкой определения времени старта сессии юзера.
всё бы хорошо, но в одном случае оно работает некорректно:
если искомая сессия является консольной сессией на сервере (windows server 2003), то почему-то вместо sessionData.Session=0 LsaGetLogonSessionData пишет другой номер сессии..

итак, вот код:

const
 WTS_CURRENT_SERVER_HANDLE = 0;

type
 PTOKEN_USER = ^TOKEN_USER;
 _TOKEN_USER = record
   User: TSidAndAttributes;
 end;
 TOKEN_USER = _TOKEN_USER;

 USHORT = word;
   
 _LSA_UNICODE_STRING = record
   Length: USHORT;
   MaximumLength: USHORT;
   Buffer: LPWSTR;
 end;
 LSA_UNICODE_STRING = _LSA_UNICODE_STRING;

 PLuid = ^LUID;
 _LUID = record
   LowPart: DWORD;
   HighPart: LongInt;
 end;
 LUID = _LUID;
 
 _SECURITY_LOGON_TYPE = (
   seltFiller0, seltFiller1,
   Interactive,
   Network,
   Batch,
   Service,
   Proxy,
   Unlock,
   NetworkCleartext,
   NewCredentials,
   RemoteInteractive,
   CachedInteractive,
   CachedRemoteInteractive);
 SECURITY_LOGON_TYPE = _SECURITY_LOGON_TYPE;

 PSECURITY_LOGON_SESSION_DATA = ^SECURITY_LOGON_SESSION_DATA;
 _SECURITY_LOGON_SESSION_DATA = record
   Size: ULONG;
   LogonId: LUID;
   UserName: LSA_UNICODE_STRING;
   LogonDomain: LSA_UNICODE_STRING;
   AuthenticationPackage: LSA_UNICODE_STRING;
   LogonType: SECURITY_LOGON_TYPE;
   Session: ULONG;
   Sid: PSID;
   LogonTime: LARGE_INTEGER;
   LogonServer: LSA_UNICODE_STRING;
   DnsDomainName: LSA_UNICODE_STRING;
   Upn: LSA_UNICODE_STRING;
 end;
 SECURITY_LOGON_SESSION_DATA = _SECURITY_LOGON_SESSION_DATA;

 _WTS_INFO_CLASS = (
   WTSInitialProgram,
   WTSApplicationName,
   WTSWorkingDirectory,
   WTSOEMId,
   WTSSessionId,
   WTSUserName,
   WTSWinStationName,
   WTSDomainName,
   WTSConnectState,
   WTSClientBuildNumber,
   WTSClientName,
   WTSClientDirectory,
   WTSClientProductId,
   WTSClientHardwareId,
   WTSClientAddress,
   WTSClientDisplay,
   WTSClientProtocolType);
 WTS_INFO_CLASS = _WTS_INFO_CLASS;

 _WTS_CONNECTSTATE_CLASS = (
   WTSActive, // User logged on to WinStation
   WTSConnected, // WinStation connected to client
   WTSConnectQuery, // In the process of connecting to client
   WTSShadow, // Shadowing another WinStation
   WTSDisconnected, // WinStation logged on without client
   WTSIdle, // Waiting for client to connect
   WTSListen, // WinStation is listening for connection
   WTSReset, // WinStation is being reset
   WTSDown, // WinStation is down due to error
   WTSInit); // WinStation in initialization
 WTS_CONNECTSTATE_CLASS = _WTS_CONNECTSTATE_CLASS;

 function LsaFreeReturnBuffer(Buffer: pointer): Integer; stdcall;

 function WTSGetActiveConsoleSessionId: DWORD; external "Kernel32.dll";

 function LsaGetLogonSessionData(LogonId: PLUID;
    var ppLogonSessionData: PSECURITY_LOGON_SESSION_DATA): LongInt; stdcall;
    external "Secur32.dll";

 function LsaNtStatusToWinError(Status: cardinal): ULONG; stdcall;
    external "Advapi32.dll";

 function LsaEnumerateLogonSessions(Count: PULONG; List: PLUID): LongInt;
    stdcall; external "Secur32.dll";

 function WTSQuerySessionInformationA(hServer: THandle; SessionId: DWORD;
    WTSInfoClass: WTS_INFO_CLASS; var pBuffer: Pointer;
    var pBytesReturned: DWORD): BOOL; stdcall; external "Wtsapi32.dll";

var
 Form1: TForm1;

implementation

uses DateUtils;

{$R *.dfm}

function LSAUnicodeStringToStr(const lsaStr : LSA_UNICODE_STRING) : string;
var
len : Integer;
begin
len := lsaStr.Length div sizeof (WideChar);
SetLength (result, len);
WideCharToMultiByte (CP_ACP, 0, lsaStr.Buffer, len,  PChar (result), len, Nil, Nil);
end;

function GMTToLocalTime(GMTTime: TDateTime): TDateTime;
var
 GMTST: Windows.TSystemTime;
 LocalST: Windows.TSystemTime;
begin
  SysUtils.DateTimeToSystemTime(GMTTime, GMTST);
  SysUtils.Win32Check(Windows.SystemTimeToTzSpecificLocalTime(nil, GMTST, LocalST));
  Result := SysUtils.SystemTimeToDateTime(LocalST);
end;

function LsaFreeReturnBuffer; external "secur32.dll" name "LsaFreeReturnBuffer";

function GetUserLogonTime(ASessionId: Integer): TDateTime;
var
  Count: cardinal;
  List: PLUID;
  sessionData: PSECURITY_LOGON_SESSION_DATA;
  i1: integer;
  SizeNeeded, SizeNeeded2: DWORD;
  OwnerName, DomainName: PChar;
  OwnerType: SID_NAME_USE;
  pBuffer: Pointer;
  pBytesreturned: DWord;
  ft: TFileTime;
  st: TSystemTime;
  dt: TDateTime;
begin
  result:= 0;  

  Form1.Memo1.Lines.Add("---- "+inttostr(ASessionId));

  i1:= lsaNtStatusToWinError(LsaEnumerateLogonSessions(@Count, @List));
  try
     if i1 = 0 then
     begin
         i1:= -1;
         if Count > 0 then
         begin  // Form1.Memo1.Lines.Add("Count > 0");
             repeat
               inc(i1);
               LsaGetLogonSessionData(List, sessionData);

               if ((sessionData.LogonType = Interactive) or (sessionData.LogonType = RemoteInteractive)) and (sessionData.Session = ASessionId) then
                 Form1.Memo1.Lines.Add("found");

                 ft.dwLowDateTime := sessionData.LogonTime.LowPart;
                 ft.dwHighDateTime := sessionData.LogonTime.HighPart;

                 FileTimeToSystemTime(ft, st);
                 dt := EncodeDateTime(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);

                 dt :=  GMTToLocalTime(dt);
                             
                 result := dt;

               Form1.Memo1.Lines.Add(format("i1=%d, user = %s, Count = %d, sessionData.LogonType=%d, sessionData.Session=%d, time = %s",
               [i1, LSAUnicodeStringToStr(sessionData.UserName), Count, integer(sessionData.LogonType), sessionData.Session,
               datetimetostr(result)]));

               inc(List);
               try
                   LSAFreeReturnBuffer(sessionData);
               except
               end;
           until (i1 = Count-1) {or (result <> 0)};
         end;
     end;
  finally
     LSAFreeReturnBuffer(List);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 ppLogonSessionData: PSECURITY_LOGON_SESSION_DATA;
 c: ULONG;
 l: PLUID;
begin
memo1.lines.add("GetCurrentSessionID = "+inttostr(GetCurrentSessionID));
memo1.lines.add(datetimetostr(GetUserLogonTime(GetCurrentSessionID)));
end;


 
istok   (2010-09-27 23:40) [1]

результат выполнения:

GetCurrentSessionID = 0
---- 0
i1=0, user = АНОНИМНЫЙ ВХОД, Count = 10, sessionData.LogonType=3, sessionData.Session=0, time = 23.09.2010 9:40:45
i1=1, user = NETWORK SERVICE, Count = 10, sessionData.LogonType=5, sessionData.Session=0, time = 23.09.2010 9:40:08
i1=2, user = ademko, Count = 10, sessionData.LogonType=10, sessionData.Session=3, time = 27.09.2010 23:20:03
i1=3, user = ademko, Count = 10, sessionData.LogonType=10, sessionData.Session=5, time = 27.09.2010 12:47:40
i1=4, user = ademko, Count = 10, sessionData.LogonType=10, sessionData.Session=7, time = 24.09.2010 17:06:02
i1=5, user = ademko, Count = 10, sessionData.LogonType=10, sessionData.Session=2, time = 23.09.2010 11:51:39
i1=6, user = ashestakov, Count = 10, sessionData.LogonType=10, sessionData.Session=1, time = 23.09.2010 9:41:44
i1=7, user = LOCAL SERVICE, Count = 10, sessionData.LogonType=5, sessionData.Session=5, time = 23.09.2010 9:40:08
i1=8, user = , Count = 10, sessionData.LogonType=0, sessionData.Session=0, time = 23.09.2010 9:40:08
i1=9, user = BELG-STUDENT$, Count = 10, sessionData.LogonType=0, sessionData.Session=0, time = 23.09.2010 9:40:08
23.09.2010 9:40:08

выделенная сессия является искомой, но почему-то её id возвращается как 3 а не 0.
вопрос - почему???

в других системах такая проблема пока больше не воспроизводилась.


 
istok   (2010-09-27 23:54) [2]

поправка: ровно такая же проблема воспроизвелась с консольной сессией на другом сервере.  с remote сессиями проблем нет.

в консольную сессию вхожу через mstsc.exe -admin из win7 (или /console из 2003ей) - может в этом дело? т.е. сессия консольная (нулевая), но удалённая..


 
Игорь Шевченко ©   (2010-09-28 00:11) [3]

Удаленная сессия не может быть нулевой.

"Первый сеанс входа на физической консоли компьютера считается нулевой сессией"


 
Eraser ©   (2010-09-28 00:23) [4]

> [3] Игорь Шевченко ©   (28.09.10 00:11)
> Удаленная сессия не может быть нулевой.

Еще как может.


 
istok   (2010-09-28 07:48) [5]

а как быть с тем, что вот эта функция возвращает 0 ? и в диспетчере задач в юзерах код сеанса тоже 0.


function GetCurrentSessionID: Integer;
// Getting the session id from the current process
type
 TProcessIdToSessionId = function(dwProcessId: DWORD; pSessionId: DWORD): BOOL; stdcall;
var
 ProcessIdToSessionId: TProcessIdToSessionId;
 hWTSapi32dll: THandle;
 Lib : THandle;
 pSessionId : DWord;
begin
 Result := 0;
 Lib := GetModuleHandle("kernel32");
 if Lib <> 0 then
 begin
   ProcessIdToSessionId := GetProcAddress(Lib, "ProcessIdToSessionId");
   if Assigned(ProcessIdToSessionId) then
   begin
     ProcessIdToSessionId(GetCurrentProcessId(), DWORD(@pSessionId));
     Result:= pSessionId;
   end;
 end;
end;


 
Anatoly Podgoretsky ©   (2010-09-28 08:52) [6]

Кто же будет читать эту портянку?


 
Eraser ©   (2010-09-29 02:25) [7]

> [5] istok   (28.09.10 07:48)

ну значит 0, а в чем проблема то не понятно?


 
han_malign   (2010-09-29 12:26) [8]


> но почему-то её id возвращается как 3 а не 0.

The WTSGetActiveConsoleSessionId function retrieves the Terminal Services session currently attached to the physical console. The physical console is the monitor, keyboard, and mouse. Note that it is not necessary that Terminal Services be running for this function to succeed.


> Удаленная сессия не может быть нулевой.
> "Первый сеанс входа на физической консоли компьютера считается нулевой сессией"

MSDN: Terminal Services Sessions
The console session on the Terminal Server is assigned the session ID 0.
- где тут physical?

KB: Q278845 (http://support.microsoft.com/kb/278845)
В Windows Server 2003 при использовании служб терминалов вы можете подключаться к сеансу консоли (сеанс 0) и одновременно открывать параллельный сеанс (если вы подключаетесь из сеанса не на консоли). Эта дополнительная функция позволит удаленно выполнять вход на сервер Windows Server 2003, на котором запущена служба терминалов, и подключаться к сеансу 0, как если бы вы физически находились за консолью компьютера. Этот сеанс можно также запускать параллельно, чтобы удаленный и локальный пользователи могли работать в одном сеансе.


 
Игорь Шевченко ©   (2010-09-29 13:11) [9]

han_malign   (29.09.10 12:26) [8]

Значит, надо сказать Соломону, чтобы исправил опечатку. Цитата оттуда, из "Внутреннего устройства Windows"


 
han_malign   (2010-09-29 13:36) [10]


> Значит, надо сказать Соломону

MSDN - Август 2006
Terminal Services: WTSQuerySessionInformation
...
Windows Server 2003 and Windows XP:  Session zero might not be attached to the physical console. This is because session zero can be attached to a remote session. Additionally, fast user switching is implemented using Terminal Services sessions. The first user to log on uses session zero, the next user to log on uses session one, and so on. To determine if your application is running on the physical console, call the WTSGetActiveConsoleSessionId function as follows:
(CurrentSessionId == WTSGetActiveConsoleSessionId ())

Windows 2000 Server and Windows 2000 Professional:  Session zero will be attached only to the physical console.

А начиная с Vista - нулевой сессии наглухо обломали доступ к физической консоли... В том числе, кажется, и разные хитрые манипуляции с модификацией жетона, олицетворением и т.п. ...



Страницы: 1 вся ветка

Текущий архив: 2010.12.26;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.008 c
15-1284469263
azamatufa
2010-09-14 17:01
2010.12.26
Помгите найти sp1 для D7


15-1284459038
Savek
2010-09-14 14:10
2010.12.26
Подмена IP адреса


2-1285874599
faiwer
2010-09-30 23:23
2010.12.26
Главная форма и модальные окна


2-1285944015
Первокурсница
2010-10-01 18:40
2010.12.26
Экспортировать отчёт из Delphi в MsWord,дублировать запрос в Lbl


15-1284409769
Юрий
2010-09-14 00:29
2010.12.26
С днем рождения ! 14 сентября 2010 вторник