Wie kann ich die SID des aktuellen Windows-Konto erhalten?
Frage
Ich bin für eine einfache Möglichkeit, die SID für das aktuelle Windows-Benutzerkonto zu erhalten. Ich weiß, dass ich es durch WMI tun kann, aber ich will nicht, diesen Weg zu gehen.
Apologies an alle, die für die nicht spezifiziert ist es C in C # beantwortet ++. : -)
Lösung
In Win32, rufen Sie GetTokenInformation , vorbei an einem Token Griff und die TokenUser
konstant. Es füllt in einer TOKEN_USER Struktur für Sie. Eines der Elemente, da drin ist der SID des Benutzers. Es ist ein BLOB (binary), aber man kann es in einen String verwandeln, indem Sie ConvertSidToStringSid .
Um halten den aktuellen Token Griff zu bekommen, verwenden Sie Open oder Open .
Wenn Sie ATL bevorzugen, hat es die CAccessToken Klasse, die alle möglichen interessanten Dinge in sich hat.
.NET hat die Thread.CurrentPrinciple Eigenschaft, die ein IPrincipal Referenz zurückgibt. Sie können den SID erhalten:
IPrincipal principal = Thread.CurrentPrincipal;
WindowsIdentity identity = principal.Identity as WindowsIdentity;
if (identity != null)
Console.WriteLine(identity.User);
Auch in .NET können Sie verwenden WindowsIdentity.GetCurrent (), die den aktuellen Benutzer-ID zurückgibt:
WindowsIdentity identity = WindowsIdentity.GetCurrent();
if (identity != null)
Console.WriteLine(identity.User);
Andere Tipps
Das sollten Sie geben, was Sie brauchen:
mit System.Security.Principal;
...
var sid = WindowsIdentity.GetCurrent () Benutzer;.
Die User-Eigenschaft von Windows gibt den SID, pro MSDN Docs
ATL::CAccessToken accessToken;
ATL::CSid currentUserSid;
if (accessToken.GetProcessToken(TOKEN_READ | TOKEN_QUERY) &&
accessToken.GetUser(¤tUserSid))
return currentUserSid.Sid();
Codeproject ein paar verschiedene Methoden hat, können Sie versuchen Sie ... nicht erwähnt, welche Sprachen Sie eine Lösung in.
gesuchtWenn Sie es über eine Batch-Datei oder etwas zugreifen möchten, können Sie als PsGetSid aussehen von Sysinternals . Er übersetzt SIDs Namen und umgekehrt.
In C # können Sie verwenden entweder
using Microsoft.Win32.Security;
...
string username = Environment.UserName + "@" + Environment.GetEnvironmentVariable("USERDNSDOMAIN");
Sid sidUser = new Sid (username);
oder ...
using System.Security.AccessControl;
using System.Security.Principal;
...
WindowsIdentity m_Self = WindowsIdentity.GetCurrent();
SecurityIdentifier m_SID = m_Self.Owner;");
fand ich eine andere Art und Weise SID zu erhalten:
System.Security.Principal.WindowsIdentity id = System.Security.Principal.WindowsIdentity.GetCurrent();
string sid = id.User.AccountDomainSid.ToString();
Und in nativen Code:
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);
Sie hat nicht angegeben, welche Sprache Sie wollen. Aber wenn Sie für C # vorhast dieser Artikel bietet sowohl die WMI-Methode sowie eine schnellere (während ausführlicher) Methode, um die Win32-API verwendet wird.
http://www.codeproject.com/KB/cs/processownersid.aspx
Ich glaube nicht, dass es noch eine andere Möglichkeit, dies zu tun, ohne WMI oder die Win32-API.
Dies ist die kürzeste von allen, glaube ich.
UserPrincipal.Current.Sid;
Erhältlich mit .net> = 3.5
Diese Frage als c++
markiert Und ich antworte in c++
Sprache, also ich empfehlen die Verwendung von WMI Werkzeug:
So, wie WMI Befehle in powershell
, brüllen Befehl erhalten SID
von system-pc1
Benutzer:
Get-WmiObject win32_useraccount -Filter "name = 'system-pc1'" | Select-Object sid
Zuerst müssen Sie aktuelle username
mit Balg code
bekommen:
char username[UNLEN+1];
DWORD username_len = UNLEN+1;
GetUserName(username, &username_len);
Jetzt können Sie mit WQL
Sprache versuchen und diese Abfrage in c++
als Gebrüll auszuführen (in diesem Beispiel habe ich von system-pc1
Benutzername in WQL_WIN32_USERACCOUNT_QUERY
Abfrage:
#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();
Dieses Beispiel funktioniert ordnungsgemäß funktioniert!