Comment puis-je obtenir le SID du compte Windows actuel?
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 ++. : -)
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: Également dans .NET, vous pouvez utiliser WindowsIdentity.GetCurrent (), qui renvoie l'ID utilisateur actuel: IPrincipal principal = Thread.CurrentPrincipal;
WindowsIdentity identity = principal.Identity as WindowsIdentity;
if (identity != null)
Console.WriteLine(identity.User);
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(¤tUserSid))
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!