summaryrefslogtreecommitdiffstats
path: root/src/detection/users/users_windows.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/detection/users/users_windows.c')
-rw-r--r--src/detection/users/users_windows.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/detection/users/users_windows.c b/src/detection/users/users_windows.c
new file mode 100644
index 0000000..4cde44e
--- /dev/null
+++ b/src/detection/users/users_windows.c
@@ -0,0 +1,61 @@
+#include "users.h"
+#include "common/windows/unicode.h"
+#include "common/time.h"
+
+#include <windows.h>
+#include <wtsapi32.h>
+#include <ws2tcpip.h>
+
+const char* ffDetectUsers(FFUsersOptions* options, FFlist* users) {
+ WTS_SESSION_INFO_1W* sessionInfo;
+ DWORD sessionCount;
+ DWORD level = 1;
+
+ if (!WTSEnumerateSessionsExW(WTS_CURRENT_SERVER_HANDLE, &level, 0, &sessionInfo, &sessionCount)) {
+ return "WTSEnumerateSessionsW(WTS_CURRENT_SERVER_HANDLE) failed";
+ }
+
+ for (DWORD i = 0; i < sessionCount; i++) {
+ WTS_SESSION_INFO_1W* session = &sessionInfo[i];
+ if (session->State != WTSActive) {
+ continue;
+ }
+
+ FF_STRBUF_AUTO_DESTROY userName = ffStrbufCreateWS(session->pUserName);
+
+ if (options->myselfOnly && !ffStrbufEqual(&instance.state.platform.userName, &userName)) {
+ continue;
+ }
+
+ FFUserResult* user = FF_LIST_ADD(FFUserResult, *users);
+ ffStrbufInitMove(&user->name, &userName);
+ ffStrbufInitWS(&user->hostName, session->pHostName);
+ ffStrbufInitWS(&user->sessionName, session->pSessionName);
+ ffStrbufInit(&user->clientIp);
+ user->loginTime = 0;
+
+ DWORD bytes = 0;
+ PWTS_CLIENT_ADDRESS address = NULL;
+ if (WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSClientAddress, (LPWSTR*) &address, &bytes)) {
+ if (address->AddressFamily == AF_INET) {
+ ffStrbufSetF(&user->clientIp, "%u.%u.%u.%u", address->Address[2], address->Address[3], address->Address[4], address->Address[5]);
+ } else if (address->AddressFamily == AF_INET6) {
+ char ipStr[INET6_ADDRSTRLEN];
+ const char* end = RtlIpv6AddressToStringA((const IN6_ADDR*) address->Address, ipStr);
+ ffStrbufSetNS(&user->clientIp, (uint32_t) (end - ipStr), ipStr);
+ }
+ WTSFreeMemory(address);
+ }
+
+ bytes = 0;
+ PWTSINFOW wtsInfo = NULL;
+ if (WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSSessionInfo, (LPWSTR*) &wtsInfo, &bytes)) {
+ user->loginTime = ffFileTimeToUnixMs((uint64_t) wtsInfo->LogonTime.QuadPart);
+ WTSFreeMemory(wtsInfo);
+ }
+ }
+
+ WTSFreeMemoryExW(WTSTypeSessionInfoLevel1, sessionInfo, 1);
+
+ return NULL;
+}