[代码] Windows 通过login_id获取uname,usid,udomain

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过期,后面代码加了缓存,用于查找旧用户信息。

点赞

本文标签: c++

版权声明:本博客所有文章除特别声明外,本文皆为《shiver blog》原创,转载请保留文章出处。

本文链接:[代码] Windows 通过login_id获取uname,usid,udomain - https://www.binary-monster.top/article/67

1

发表评论

电子邮件地址不会被公开。 必填项已用*标注