Question

Je recherche un moyen simple d’obtenir le SID du compte utilisateur Windows actuel. Je sais que je peux le faire via WMI, mais je ne veux pas aller dans cette voie.

Toutes mes excuses à tous ceux qui ont répondu en C # pour ne pas avoir spécifié le C ++. : -)

Était-ce utile?

La solution

Sous Win32, appelez GetTokenInformation , en transmettant un descripteur de jeton et le Constante TokenUser . Il complétera pour vous une TOKEN_USER structure. L'un des éléments est le SID de l'utilisateur. C'est un BLOB (binaire), mais vous pouvez le transformer en chaîne en utilisant ConvertSidToStringSid .

Pour obtenir le pseudo actuel du jeton, utilisez OpenThreadToken. ou OpenProcessToken .

Si vous préférez ATL, le CAccessToken

.NET possède le Thread.CurrentPrinciple propriété, qui retourne une référence IPrincipal. Vous pouvez obtenir le SID:

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

Également dans .NET, vous pouvez utiliser WindowsIdentity.GetCurrent (), qui renvoie l'ID utilisateur actuel:

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

Autres conseils

Cela devrait vous donner ce dont vous avez besoin:

using System.Security.Principal;

...

var sid = WindowsIdentity.GetCurrent (). User;

La propriété User de WindowsIdentity renvoie le SID, conformément à MSDN Docs

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

CodeProject a plusieurs méthodes que vous pouvez essayer ... Vous pouvez essayer ne mentionnez pas les langues dans lesquelles vous souhaitiez une solution.

Si vous souhaitez y accéder via un fichier de commandes ou quelque chose d'autre, vous pouvez regarder comme PsGetSid par Sysinternals . Il traduit les SID en noms et vice versa.

En C #, vous pouvez utiliser soit

utilisant Microsoft.Win32.Security;

...

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

Sid sidUser = new Sid (nom d'utilisateur);

Ou ...

using System.Security.AccessControl;

utilisant System.Security.Principal;

...

WindowsIdentity m_Self = WindowsIdentity.GetCurrent ();

SecurityIdentifier m_SID = m_Self.Owner; ");

J'ai trouvé un autre moyen d'obtenir le SID:

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

Et en code natif:

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);

Vous n'avez pas spécifié la langue que vous voulez. Mais si vous êtes prêt pour C #, cet article propose à la fois la méthode WMI et une méthode plus rapide (bien que plus détaillée) utilisant l’API Win32.

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

Je ne pense pas qu'il existe actuellement un autre moyen de le faire sans utiliser WMI ou l'API Win32.

Celui-ci est le plus court de tous, je crois.

UserPrincipal.Current.Sid;

Disponible avec .net > = 3,5

Cette question porte le libellé c ++ . Et je réponds dans le langage c ++ . Je vous recommande donc d'utiliser WMI . outil:

Ainsi, en tant que commandes WMI dans powershell , la commande ci-dessous obtient le SID de system-pc1 utilisateur:

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

Tout d'abord, vous devez obtenir le nom d'utilisateur actuel avec le code ci-dessous :

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

Maintenant, vous pouvez essayer avec le langage WQL et exécuter cette requête dans c ++ comme suit (dans cet exemple, j’ai utilisé system-pc1 . nom d'utilisateur dans la requête 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();

Cet exemple fonctionne correctement!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top