Windows 通过login_id获取uname,usid,udomain
#include <windows.h>
#include <stdint.h>
#include <sddl.h>
#include <string>
#include <Ntsecapi.h>
#pragma comment(lib,"Secur32.lib")
int GetProcessUserNameAndSidAndDomainByLoginId(const uint64_t login_id,
std::wstring& proc_uname,
std::wstring& proc_usid,
std::wstring& proc_udomain) {
int ret = 1;
do {
if (login_id < 0) {
break;
}
PSECURITY_LOGON_SESSION_DATA sessionData = nullptr;
NTSTATUS retval =
LsaGetLogonSessionData((PLUID)&login_id, &sessionData);
if (retval == 0) {
if (login_id == 999) {
proc_uname = L"SYSTEM";
}
else {
std::wstring wstr_uname(
sessionData->UserName.Buffer,
sessionData->UserName.Length / sizeof(WCHAR));
proc_uname = wstr_uname;
}
std::wstring wstr_domain(
sessionData->LogonDomain.Buffer,
sessionData->LogonDomain.Length / sizeof(WCHAR));
proc_usid = wstr_domain;
LPWSTR wstr_usid = nullptr;
BOOL b_con =
ConvertSidToStringSidW(sessionData->Sid, &wstr_usid);
if (b_con) {
proc_usid = wstr_usid;
LocalFree(wstr_usid);
}
if (sessionData) {
LsaFreeReturnBuffer(sessionData);
}
ret = 0;
}
} while (false);
if (ret == 1) {
ret = 0;
if (login_id == 999) {
proc_uname = L"SYSTEM";
proc_usid = L"S-1-5-18";
}
else if (login_id == 997) {
proc_uname = L"LOCAL SERVICE";
proc_usid = L"S-1-5-19";
}
else if (login_id == 996) {
proc_uname = L"NETWORK SERVICE";
proc_usid = L"S-1-5-20";
}
else {
ret = 1;
}
}
return ret;
}
int main() {
uint64_t login_id = 999;
std::wstring proc_uname;
std::wstring proc_usid;
std::wstring proc_udomain;
int ret = GetProcessUserNameAndSidAndDomainByLoginId(login_id, proc_uname, proc_usid, proc_udomain);
if (ret != 0) {
printf("failed");
}
else {
printf("uname:%S ,uid:%S,udomain:%S", proc_uname.c_str(), proc_usid.c_str(), proc_udomain.c_str());
}
system("pause");
return 0;
}
记录坑
windows server 2012R1机器会调用LsaGetLogonSessionData返回0xC0000017L
STATUS_NO_MEMORY
以及 0xC000005FL
STATUS_NO_SUCH_LOGON_SESSION
前者,迄今不知道原因,离谱,用demo在机器跑没有问题,放到项目的代码里面跑就有问题。
后者,可能session退出了,导致对应的login_id过期,后面代码加了缓存,用于查找旧用户信息。