Как я могу получить SID текущей учетной записи Windows?

Я ищу простой способ получить SID для текущей учетной записи пользователя Windows. Я знаю, что могу сделать это через WMI, но я не хочу идти по этому пути.

Приношу свои извинения всем, кто ответил на C# за то, что не указал C++. :-)

язык программирования / среда?

Joel Coehoorn 30.10.2008 21:31
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
31
1
39 314
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

У CodeProject есть несколько различных методов, которые вы можете попробовать ... Вы не упомянули, на каких языках вам нужно решение.

Если вы хотите получить к нему доступ через командный файл или что-то в этом роде, вы можете выглядеть как PsGetSid от Sysinternals. Он переводит идентификаторы безопасности в имена и наоборот.

Вы не указали, какой язык вам нужен. Но если вы знакомы с C#, эта статья предлагает как метод WMI, так и более быстрый (хотя и более подробный) метод с использованием Win32 API.

http://www.codeproject.com/KB/cs/processownersid.aspx

Я не думаю, что в настоящее время есть другой способ сделать это без использования WMI или Win32 API.

Это должно дать вам то, что вам нужно:

с использованием System.Security.Principal;

...

var sid = WindowsIdentity.GetCurrent (). Пользователь;

Свойство User объекта WindowsIdentity возвращает идентификатор безопасности для каждого Документы MSDN.

Ответ принят как подходящий

В Win32 вызовите GetTokenInformation, передав дескриптор токена и константу TokenUser. Он заполнит для вас структуру TOKEN_USER. Одним из элементов в нем является SID пользователя. Это BLOB (двоичный), но вы можете превратить его в строку с помощью ConvertSidToStringSid.

Чтобы получить текущий дескриптор токена, используйте OpenThreadToken или OpenProcessToken.

Если вы предпочитаете ATL, у него есть класс CAccessToken, в котором есть много интересного.

.NET имеет свойство Thread.CurrentPrinciple, которое возвращает ссылку IPrincipal. Вы можете получить SID:

IPrincipal principal = Thread.CurrentPrincipal;
WindowsIdentity identity = principal.Identity as WindowsIdentity;
if (identity != null)
    Console.WriteLine(identity.User);

Также в .NET вы можете использовать WindowsIdentity.GetCurrent (), которая возвращает текущий идентификатор пользователя:

WindowsIdentity identity = WindowsIdentity.GetCurrent();
if (identity != null)
    Console.WriteLine(identity.User);

В C# вы можете использовать либо

using Microsoft.Win32.Security;

...

string username = Environment.UserName + "@" + Environment.GetEnvironmentVariable("USERDNSDOMAIN");

Sid sidUser = new Sid (username);

Или же...

using System.Security.AccessControl;

using System.Security.Principal;

...

WindowsIdentity m_Self = WindowsIdentity.GetCurrent();

SecurityIdentifier m_SID = m_Self.Owner;");

Я нашел другой способ получить SID:

System.Security.Principal.WindowsIdentity id = System.Security.Principal.WindowsIdentity.GetCurrent();
string sid = id.User.AccountDomainSid.ToString();

Это sid домена, а не учетной записи пользователя, используйте id.User.ToString () для sid пользователя

ben or 05.11.2018 19:27

Я считаю, что это самый короткий из них.

UserPrincipal.Current.Sid;

Доступно с .net> = 3.5

ATL::CAccessToken accessToken;
ATL::CSid currentUserSid;
if (accessToken.GetProcessToken(TOKEN_READ | TOKEN_QUERY) &&
    accessToken.GetUser(&currentUserSid))
    return currentUserSid.Sid();

Это очень лаконично.

Fernando Gonzalez Sanchez 13.10.2016 22:50

И в собственном коде:

function GetCurrentUserSid: string;

    hAccessToken: THandle;
    userToken: PTokenUser;
    dwInfoBufferSize: DWORD;
    dw: DWORD;

    if not OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True, ref hAccessToken) then
        dw <- GetLastError;
        if dw <> ERROR_NO_TOKEN then
            RaiseLastOSError(dw);

        if not OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, ref hAccessToken) then
            RaiseLastOSError;
    try
        userToken <- GetMemory(1024);
        try
            if not GetTokenInformation(hAccessToken, TokenUser, userToken, 1024, ref dwInfoBufferSize) then
                RaiseLastOSError;
            Result <- SidToString(userToken.User.Sid);
        finally
            FreeMemory(userToken);
    finally
        CloseHandle(hAccessToken);

Этот вопрос помечен как c++, и я отвечаю на языке c++, поэтому я рекомендую использовать инструмент WMI:

Итак, как команды WMI в powershell, следующая команда получает SID пользователя system-pc1:

Get-WmiObject win32_useraccount -Filter "name = 'system-pc1'" | Select-Object sid

Во-первых, вам нужно получить текущий username с помощью нижеуказанного code:

char username[UNLEN+1];
DWORD username_len = UNLEN+1;
GetUserName(username, &username_len);

Теперь вы можете попробовать использовать язык WQL и выполнить этот запрос в c++, как показано ниже (в этом примере я использовал имя пользователя system-pc1 в запросе WQL_WIN32_USERACCOUNT_QUERY:

#define                 NETWORK_RESOURCE                    "root\\CIMV2"
#define                 WQL_LANGUAGE                        "WQL"
#define                 WQL_WIN32_USERACCOUNT_QUERY         "SELECT * FROM Win32_Useraccount where name='system-pc1'"
#define                 WQL_SID                             "SID"

IWbemLocator            *pLoc = 0;              // Obtain initial locator to WMI to a particular host computer
IWbemServices           *pSvc = 0;              // To use of connection that created with CoCreateInstance()
ULONG                   uReturn = 0;
HRESULT                 hResult = S_OK;         // Result when we initializing
IWbemClassObject        *pClsObject = NULL;     // A class for handle IEnumWbemClassObject objects
IEnumWbemClassObject    *pEnumerator = NULL;    // To enumerate objects
VARIANT                 vtSID = { 0 };          // OS name property

// Initialize COM library
hResult = CoInitializeEx(0, COINIT_MULTITHREADED);
if (SUCCEEDED(hResult))
{
    // Initialize security
    hResult = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT,
        RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
    if (SUCCEEDED(hResult))
    {
        // Create only one object on the local system
        hResult = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
            IID_IWbemLocator, (LPVOID*)&pLoc);

        if (SUCCEEDED(hResult))
        {
            // Connect to specific host system namespace
            hResult = pLoc->ConnectServer(TEXT(NETWORK_RESOURCE), NULL, NULL,
                0, NULL, 0, 0, &pSvc);
            if (SUCCEEDED(hResult))
            {
                /* Set the IWbemServices proxy
                * So the impersonation of the user will be occurred */
                hResult = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,
                    NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE,
                    NULL, EOAC_NONE);
                if (SUCCEEDED(hResult))
                {
                    /* Use the IWbemServices pointer to make requests of WMI
                    * For example, query for user account */
                    hResult = pSvc->ExecQuery(TEXT(WQL_LANGUAGE), TEXT(WQL_WIN32_USERACCOUNT_QUERY),
                        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
                    if (SUCCEEDED(hResult))
                    {
                        // Go to get the next object from IEnumWbemClassObject
                        pEnumerator->Next(WBEM_INFINITE, 1, &pClsObject, &uReturn);
                        if (uReturn != 0)
                        {
                            // Get the value of the "sid, ..." property
                            pClsObject->Get(TEXT(WQL_SID), 0, &vtSID, 0, 0);
                            VariantClear(&vtSID);

                            // Print SID
                            wcout << vtSID.bstrVal;

                            pClsObject->Release();
                            pClsObject = NULL;
                        }
                    }
                }
            }
        }
    }

    // Cleanup
    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    // Uninitialize COM library
    CoUninitialize();

Этот пример работает правильно!

в cmd.exe

whoami /user

если вам это нужно программно, пожалуйста, уточняйте

Опрашивающий конкретно запрашивает решение C++.

HansHirse 14.11.2019 13:04

Достаточно справедливо, называя system("whoami /user");является технически решением C++, и я должен был указать, что я хотел бы сделать это путем прямого вызова Windows API.

Franci Penov 14.11.2019 21:02

Другие вопросы по теме