use terminal services api to query for RDP logins, adding to who_list
This commit is contained in:
parent
1212c2f03e
commit
f64b36c0bd
|
@ -97,6 +97,84 @@ typedef struct _IP_ADAPTER_INFO {
|
|||
|
||||
/* end iptypes.h */
|
||||
|
||||
/* from wtsapi32.h not in vs6.0 */
|
||||
typedef enum {
|
||||
WTSInitialProgram,
|
||||
WTSApplicationName,
|
||||
WTSWorkingDirectory,
|
||||
WTSOEMId,
|
||||
WTSSessionId,
|
||||
WTSUserName,
|
||||
WTSWinStationName,
|
||||
WTSDomainName,
|
||||
WTSConnectState,
|
||||
WTSClientBuildNumber,
|
||||
WTSClientName,
|
||||
WTSClientDirectory,
|
||||
WTSClientProductId,
|
||||
WTSClientHardwareId,
|
||||
WTSClientAddress,
|
||||
WTSClientDisplay,
|
||||
WTSClientProtocolType,
|
||||
} WTS_INFO_CLASS;
|
||||
|
||||
typedef enum _WTS_CONNECTSTATE_CLASS {
|
||||
WTSActive,
|
||||
WTSConnected,
|
||||
WTSConnectQuery,
|
||||
WTSShadow,
|
||||
WTSDisconnected,
|
||||
WTSIdle,
|
||||
WTSListen,
|
||||
WTSReset,
|
||||
WTSDown,
|
||||
WTSInit
|
||||
} WTS_CONNECTSTATE_CLASS;
|
||||
|
||||
#define WTS_PROTOCOL_TYPE_CONSOLE 0
|
||||
#define WTS_PROTOCOL_TYPE_ICA 1
|
||||
#define WTS_PROTOCOL_TYPE_RDP 2
|
||||
|
||||
typedef struct _WTS_SESSION_INFO {
|
||||
DWORD SessionId;
|
||||
LPTSTR pWinStationName;
|
||||
DWORD State;
|
||||
} WTS_SESSION_INFO, *PWTS_SESSION_INFO;
|
||||
|
||||
typedef struct _WTS_PROCESS_INFO {
|
||||
DWORD SessionId;
|
||||
DWORD ProcessId;
|
||||
LPSTR pProcessName;
|
||||
PSID pUserSid;
|
||||
} WTS_PROCESS_INFO, *PWTS_PROCESS_INFO;
|
||||
|
||||
typedef struct _WTS_CLIENT_ADDRESS {
|
||||
DWORD AddressFamily;
|
||||
BYTE Address[20];
|
||||
} WTS_CLIENT_ADDRESS, *PWTS_CLIENT_ADDRESS;
|
||||
|
||||
/* the WINSTATION_INFO stuff here is undocumented
|
||||
* got the howto from google groups:
|
||||
* http://redirx.com/?31gy
|
||||
*/
|
||||
typedef enum _WINSTATION_INFO_CLASS {
|
||||
WinStationInformation = 8
|
||||
} WINSTATION_INFO_CLASS;
|
||||
|
||||
typedef struct _WINSTATION_INFO {
|
||||
BYTE Reserved1[72];
|
||||
ULONG SessionId;
|
||||
BYTE Reserved2[4];
|
||||
FILETIME ConnectTime;
|
||||
FILETIME DisconnectTime;
|
||||
FILETIME LastInputTime;
|
||||
FILETIME LoginTime;
|
||||
BYTE Reserved3[1096];
|
||||
FILETIME CurrentTime;
|
||||
} WINSTATION_INFO, *PWINSTATION_INFO;
|
||||
|
||||
/* end wtsapi32.h */
|
||||
|
||||
#include <iprtrmib.h>
|
||||
|
||||
/* undocumented structures */
|
||||
|
@ -126,7 +204,6 @@ typedef struct {
|
|||
} MIB_UDPEXTABLE, *PMIB_UDPEXTABLE;
|
||||
|
||||
/* end undocumented structures */
|
||||
|
||||
typedef DWORD (CALLBACK *LPGETIPFORWARDTABLE)(PMIB_IPFORWARDTABLE, PULONG, BOOL);
|
||||
|
||||
typedef DWORD (CALLBACK *LPGETIFTABLE)(PMIB_IFTABLE, PULONG, BOOL);
|
||||
|
@ -153,6 +230,24 @@ typedef BOOL (CALLBACK *LPENUMMODULES)(HANDLE, HMODULE*,
|
|||
typedef DWORD (CALLBACK *LPGETMODULENAME)(HANDLE, HMODULE,
|
||||
LPTSTR, DWORD);
|
||||
|
||||
typedef BOOLEAN (CALLBACK *LPSTATIONQUERYINFO)(HANDLE,
|
||||
ULONG,
|
||||
WINSTATION_INFO_CLASS,
|
||||
PVOID, ULONG, PULONG);
|
||||
|
||||
typedef BOOL (CALLBACK *LPWTSENUMERATESESSIONS)(HANDLE,
|
||||
DWORD,
|
||||
DWORD,
|
||||
PWTS_SESSION_INFO *,
|
||||
DWORD *);
|
||||
|
||||
typedef void (CALLBACK *LPWTSFREEMEMORY)(PVOID);
|
||||
|
||||
typedef BOOL (CALLBACK *LPWTSQUERYSESSION)(HANDLE,
|
||||
DWORD,
|
||||
WTS_INFO_CLASS,
|
||||
LPSTR *, DWORD *);
|
||||
|
||||
/* no longer in the standard header files */
|
||||
typedef struct {
|
||||
LARGE_INTEGER IdleTime;
|
||||
|
@ -187,6 +282,8 @@ struct sigar_t {
|
|||
HINSTANCE ip_handle;
|
||||
HINSTANCE nt_handle;
|
||||
HINSTANCE ps_handle;
|
||||
HINSTANCE wts_handle;
|
||||
HINSTANCE sta_handle;
|
||||
LPGETIFTABLE get_if_table;
|
||||
LPGETIPFORWARDTABLE get_ipforward_table;
|
||||
LPGETTCPTABLE get_tcp_table;
|
||||
|
@ -199,6 +296,10 @@ struct sigar_t {
|
|||
LPENUMMODULES enum_modules;
|
||||
LPGETMODULENAME get_module_name;
|
||||
sigar_win32_pinfo_t pinfo;
|
||||
LPSTATIONQUERYINFO query_station;
|
||||
LPWTSENUMERATESESSIONS wts_enum_sessions;
|
||||
LPWTSFREEMEMORY wts_free;
|
||||
LPWTSQUERYSESSION wts_query_session;
|
||||
WORD ws_version;
|
||||
int ws_error;
|
||||
LPBYTE peb; //scratch pad for getting peb info
|
||||
|
|
|
@ -258,6 +258,20 @@ int sigar_os_open(sigar_t **sigar)
|
|||
(*sigar)->ps_handle = NULL;
|
||||
}
|
||||
|
||||
if ((h = LoadLibrary("wtsapi32.dll"))) {
|
||||
(*sigar)->wts_handle = h;
|
||||
}
|
||||
else {
|
||||
(*sigar)->wts_handle = NULL;
|
||||
}
|
||||
|
||||
if ((h = LoadLibrary("winsta.dll"))) {
|
||||
(*sigar)->sta_handle = h;
|
||||
}
|
||||
else {
|
||||
(*sigar)->sta_handle = NULL;
|
||||
}
|
||||
|
||||
(*sigar)->pinfo.pid = -1;
|
||||
(*sigar)->ws_version = 0;
|
||||
(*sigar)->ncpu = 0;
|
||||
|
@ -288,6 +302,14 @@ int sigar_os_close(sigar_t *sigar)
|
|||
FreeLibrary(sigar->ps_handle);
|
||||
}
|
||||
|
||||
if (sigar->wts_handle) {
|
||||
FreeLibrary(sigar->wts_handle);
|
||||
}
|
||||
|
||||
if (sigar->sta_handle) {
|
||||
FreeLibrary(sigar->sta_handle);
|
||||
}
|
||||
|
||||
if (sigar->ws_version != 0) {
|
||||
WSACleanup();
|
||||
}
|
||||
|
@ -2061,6 +2083,8 @@ int sigar_who_list_get_win32(sigar_t *sigar,
|
|||
|
||||
sigar_who_registry(sigar, wholist);
|
||||
|
||||
sigar_who_wts(sigar, wholist);
|
||||
|
||||
return SIGAR_OK;
|
||||
}
|
||||
|
||||
|
@ -2235,3 +2259,123 @@ static int sigar_who_registry(sigar_t *sigar,
|
|||
|
||||
return SIGAR_OK;
|
||||
}
|
||||
|
||||
static int sigar_who_wts(sigar_t *sigar,
|
||||
sigar_who_list_t *wholist)
|
||||
{
|
||||
DWORD count, i;
|
||||
WTS_SESSION_INFO *sessions = NULL;
|
||||
|
||||
if (!sigar->wts_enum_sessions && sigar->wts_handle) {
|
||||
sigar->wts_enum_sessions =
|
||||
(LPWTSENUMERATESESSIONS)GetProcAddress(sigar->wts_handle,
|
||||
"WTSEnumerateSessionsA");
|
||||
sigar->wts_free =
|
||||
(LPWTSFREEMEMORY)GetProcAddress(sigar->wts_handle,
|
||||
"WTSFreeMemory");
|
||||
sigar->wts_query_session =
|
||||
(LPWTSQUERYSESSION)GetProcAddress(sigar->wts_handle,
|
||||
"WTSQuerySessionInformationA");
|
||||
sigar->query_station =
|
||||
(LPSTATIONQUERYINFO)GetProcAddress(sigar->sta_handle,
|
||||
"WinStationQueryInformationW");
|
||||
}
|
||||
if (!sigar->wts_enum_sessions) {
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
if (!sigar->wts_enum_sessions(0, 0, 1, &sessions, &count)) {
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
DWORD bytes;
|
||||
LPTSTR buffer;
|
||||
DWORD sessionId = sessions[i].SessionId;
|
||||
WINSTATION_INFO station_info;
|
||||
sigar_who_t *who;
|
||||
|
||||
if (sessions[i].State != WTSActive) {
|
||||
continue;
|
||||
}
|
||||
|
||||
buffer = NULL;
|
||||
bytes = 0;
|
||||
if (sigar->wts_query_session(0,
|
||||
sessionId,
|
||||
WTSClientProtocolType,
|
||||
&buffer,
|
||||
&bytes))
|
||||
{
|
||||
DWORD type = *buffer;
|
||||
sigar->wts_free(buffer);
|
||||
|
||||
if (type == WTS_PROTOCOL_TYPE_CONSOLE) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
SIGAR_WHO_LIST_GROW(wholist);
|
||||
who = &wholist->data[wholist->number++];
|
||||
|
||||
SIGAR_SSTRCPY(who->device, sessions[i].pWinStationName);
|
||||
|
||||
buffer = NULL;
|
||||
bytes = 0;
|
||||
if (sigar->wts_query_session(0,
|
||||
sessionId,
|
||||
WTSClientAddress,
|
||||
&buffer,
|
||||
&bytes))
|
||||
{
|
||||
PWTS_CLIENT_ADDRESS client =
|
||||
(PWTS_CLIENT_ADDRESS)buffer;
|
||||
|
||||
sprintf(who->host, "%u.%u.%u.%u",
|
||||
client->Address[2],
|
||||
client->Address[3],
|
||||
client->Address[4],
|
||||
client->Address[5]);
|
||||
|
||||
sigar->wts_free(buffer);
|
||||
}
|
||||
else {
|
||||
SIGAR_SSTRCPY(who->host, "unknown");
|
||||
}
|
||||
|
||||
buffer = NULL;
|
||||
bytes = 0;
|
||||
if (sigar->wts_query_session(0,
|
||||
sessionId,
|
||||
WTSUserName,
|
||||
&buffer,
|
||||
&bytes))
|
||||
{
|
||||
SIGAR_SSTRCPY(who->user, buffer);
|
||||
sigar->wts_free(buffer);
|
||||
}
|
||||
else {
|
||||
SIGAR_SSTRCPY(who->user, "unknown");
|
||||
}
|
||||
|
||||
buffer = NULL;
|
||||
bytes = 0;
|
||||
if (sigar->query_station(0,
|
||||
sessionId,
|
||||
WinStationInformation,
|
||||
&station_info,
|
||||
sizeof(station_info),
|
||||
&bytes))
|
||||
{
|
||||
who->time =
|
||||
FileTimeToTime(&station_info.ConnectTime) / 1000000;
|
||||
}
|
||||
else {
|
||||
who->time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
sigar->wts_free(sessions);
|
||||
|
||||
return SIGAR_OK;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue