![]() |
Feststellen, ob "Als Administrator" ausgeführt
Wie kann man feststellen, ob das eigene Programm oder ein anderes mit "Als Administrator ausführen" gestartet wurde. Wenn man unter Windows 10 z.B. ein CMD-Fenster öffnet (CMD.EXE), dann wird im Titel "Administrator: Eingabeaufforderung" angezeigt. Das Programm CMD.EXE bemerkt dieses Sachverhalt.
Wie fragt man das ab ? Gibt es ein Tool, mit dem man feststellen kann, ob ein Programm so gestartet wurde oder auch nicht ? |
AW: Feststellen, ob "Als Administrator" ausgeführt
![]() Zitat:
Man kann garantiert auch den Token eines fremden Programms prüfen. |
AW: Feststellen, ob "Als Administrator" ausgeführt
hier
![]() Gruß K-H |
AW: Feststellen, ob "Als Administrator" ausgeführt
Liste der Anhänge anzeigen (Anzahl: 1)
Ich meine den Sachverhalt, wenn man das Programm mit Als Administrator ausführen startet.
|
AW: Feststellen, ob "Als Administrator" ausgeführt
Ja, es wird mit den Rechten des/eines Adminaccounts gestartet, was aber nicht bedeutet, dass das Programm dann auch alle Rechte hat, vorallem die nicht, welche man vorher dem Admin weggenommen hat. :stupid:
|
AW: Feststellen, ob "Als Administrator" ausgeführt
Zitat:
Es geht also um die Rolle. Und die fragt man so ab:
Delphi-Quellcode:
(Quelle:
uses
Winapi.Windows; // <= die wird Minimum benötigt function IsUserAdmin: Boolean; var b: BOOL; AdministratorsGroup: PSID; begin { This function returns true if you are currently running with admin privileges. In Vista and later, if you are non-elevated, this function will return false (you are not running with administrative privileges). If you *are* running elevated, then IsUserAdmin will return true, as you are running with admin privileges. Windows provides this similar function in Shell32.IsUserAnAdmin. But the function is deprecated, and this code is lifted from the docs for CheckTokenMembership: http://msdn.microsoft.com/en-us/library/aa376389.aspx } { Routine Description: This routine returns TRUE if the callers process is a member of the Administrators local group. Caller is NOT expected to be impersonating anyone and is expected to be able to open its own process and process token. Arguments: None. Return Value: TRUE - Caller has Administrators local group. FALSE - Caller does not have Administrators local group. } b := AllocateAndInitializeSid( SECURITY_NT_AUTHORITY, 2, //2 sub-authorities SECURITY_BUILTIN_DOMAIN_RID, //sub-authority 0 DOMAIN_ALIAS_RID_ADMINS, //sub-authority 1 0, 0, 0, 0, 0, 0, //sub-authorities 2-7 not passed AdministratorsGroup); if (b) then begin if not CheckTokenMembership(0, AdministratorsGroup, b) then b := False; FreeSid(AdministratorsGroup); end; Result := b; end; ![]() Nach genauer Analyse kräuseln sich mir bei so einem Code allerdings die Fußnägel, darum hier nochmal so, wie man das machen sollte:
Delphi-Quellcode:
Sauber, sicher und im Ernstfall sogar kommunikativ :stupid:
unit Unit3;
interface function IsUserAdmin: Boolean; implementation uses Winapi.Windows, System.SysUtils; Const SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5)); SECURITY_BUILTIN_DOMAIN_RID = $00000020; DOMAIN_ALIAS_RID_ADMINS = $00000220; DOMAIN_ALIAS_RID_USERS = $00000221; DOMAIN_ALIAS_RID_GUESTS = $00000222; DOMAIN_ALIAS_RID_POWER_USERS= $00000223; function CheckTokenMembership(TokenHandle: THandle; SidToCheck: PSID; var IsMember: BOOL): BOOL; stdcall; external advapi32; function IsUserAdmin: Boolean; var IsMember : BOOL; AdministratorsGroup: PSID; begin Win32Check( AllocateAndInitializeSid( {} SECURITY_NT_AUTHORITY, {} 2, // 2 sub-authorities {} SECURITY_BUILTIN_DOMAIN_RID, // sub-authority 0 {} DOMAIN_ALIAS_RID_ADMINS, // sub-authority 1 {} 0, 0, 0, 0, 0, 0, // sub-authorities 2-7 not passed {} AdministratorsGroup ) ); try Win32Check( CheckTokenMembership( 0, AdministratorsGroup, IsMember ) ); finally FreeSid( AdministratorsGroup ); end; Result := IsMember; end; end. |
AW: Feststellen, ob "Als Administrator" ausgeführt
Zitat:
In manchen Fällen prüfe ich allerdings auch beim Programmstart, ob meine Anwendung mit einem Elevated-Token gestartet wurde, um bestimmte (kontextual weniger wichtige) Aktionen dann zu unterlassen. @Sir Rufo: Das ist ab Vista auch nur halb korrekt. Wenn du einen Adminaccount hast, wird das Programm auch in dessem Kontext gestartet. Standardmäßig allerdings mit dem eingeschränkten Token. Das hier sollte seinen Dienst tun:
Delphi-Quellcode:
type
TPrivilegeLevel = (plLimited, plAdmin, plAdminElevated); function QueryPrivilegeLevel(const UseThreadToken: Boolean): TPrivilegeLevel; function GetAdminSid: PSID; const SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5)); SECURITY_BUILTIN_DOMAIN_RID: DWord = $00000020; DOMAIN_ALIAS_RID_ADMINS : DWord = $00000220; begin Result := nil; AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, Result); end; const SE_GROUP_USE_FOR_DENY_ONLY = $00000010; var TokenHandle: THandle; ReturnLength: DWORD; TokenInformation: PTokenGroups; AdminSid: PSID; Loop: Integer; begin Result := plLimited; if (UseThreadToken) then begin if not OpenThreadToken(GetCurrentThread, TOKEN_QUERY, true, TokenHandle) then Exit; end else begin if not OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, TokenHandle) then Exit; end; if (TokenHandle <> 0) then try ReturnLength := 0; GetTokenInformation(TokenHandle, TokenGroups, nil, 0, ReturnLength); TokenInformation := GetMemory(ReturnLength); if Assigned(TokenInformation) then try if GetTokenInformation(TokenHandle, TokenGroups, TokenInformation, ReturnLength, ReturnLength) then begin AdminSid := GetAdminSid; for Loop := 0 to TokenInformation^.GroupCount - 1 do begin if EqualSid(TokenInformation^.Groups[Loop].Sid, AdminSid) then begin if ((TokenInformation^.Groups[Loop].Attributes and SE_GROUP_USE_FOR_DENY_ONLY) = SE_GROUP_USE_FOR_DENY_ONLY) then begin Result := plAdmin; end else begin Result := plAdminElevated; end; Break; end; end; FreeSid(AdminSid); end; finally FreeMemory(TokenInformation); end; finally CloseHandle(TokenHandle); end; end; |
AW: Feststellen, ob "Als Administrator" ausgeführt
Zitat:
Und wenn der von dir für OK befundene Administrator das nötigt Recht nicht besitzt, dann geht deine Prüfung auch schief, da sie zwar "JA, ist ein Administrator" sagt, es aber dennoch NEIN heißen müsste. Wenn du das Programm direkt im AdminAcc startest, dann sagt das auch "der ist bei den Administratoren", aber UAC hat das Programm standardmäßig dennoch eingeschränkt. :stupid: Und dann gibt es eventuell noch Benutzer mit den nötigen Rechten, die aber keine Administratoren sind. |
AW: Feststellen, ob "Als Administrator" ausgeführt
Es wurden schon (soweit ich das beurteilen kann) gute Antworten gepostet aber da ich noch nie mit sowas zu tun hatte habe ich mich selbst mal dran gesetzt:
Delphi-Quellcode:
Was ist daran schlecht/ungünstig?
function IsRunAsAdmin: Boolean;
const WinBuiltinAdministratorsSid = 26; var sidlen: Cardinal; sid: PSID; isAdmin: BOOL; begin Result := false; CreateWellKnownSid(WinBuiltinAdministratorsSid, nil , nil, @sidlen); GetMem(sid, sidlen); try if CreateWellKnownSid(WinBuiltinAdministratorsSid, nil , sid, @sidlen) then begin try if CheckTokenMembership(0, Sid, isAdmin) then Result := isAdmin; finally FreeSid(sid); end; end finally FreeMem(sid); end; end; Was mich auch verwirrt: Muss ich in dem Fall FreeSid aufrufen? Und wenn ja, muss ich dann auch noch FreeMem aufrufen? Ansonsten hab ichs getestet und es scheint zumindest zu funktionieren. Wahrscheinlich sollte ich Exceptions werfen, statt false zurückzugeben wenn eine API fehlschlägt. Aber ansonsten müsste das doch in Ordnung sein oder? Kritik ist erwünscht. |
AW: Feststellen, ob "Als Administrator" ausgeführt
Ist ähnlich wie hier:
![]()
Delphi-Quellcode:
program TestAdmin;
{$IFDEF FPC} {$mode objfpc}{$H+} {$ELSE} {$APPTYPE CONSOLE} {$ENDIF} uses SysUtils, Windows, Classes; Const SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5)); SECURITY_BUILTIN_DOMAIN_RID = $00000020; DOMAIN_ALIAS_RID_ADMINS = $00000220; DOMAIN_ALIAS_RID_USERS = $00000221; DOMAIN_ALIAS_RID_GUESTS = $00000222; DOMAIN_ALIAS_RID_POWER_USERS= $00000223; function CheckTokenMembership(TokenHandle: THandle; SidToCheck: PSID; var IsMember: BOOL): BOOL; stdcall; external advapi32; function UserInGroup(Group :DWORD) : Boolean; var pIdentifierAuthority :TSIDIdentifierAuthority; pSid : Windows.PSID; IsMember : BOOL; begin pIdentifierAuthority := SECURITY_NT_AUTHORITY; Result := AllocateAndInitializeSid(pIdentifierAuthority,2, SECURITY_BUILTIN_DOMAIN_RID, Group, 0, 0, 0, 0, 0, 0, pSid); try if Result then if not CheckTokenMembership(0, pSid, IsMember) then //passing 0 means which the function will be use the token of the calling thread. Result:= False else Result:=IsMember; finally FreeSid(pSid); end; end; begin Writeln(Format('Current user is Admin %s', [BoolToStr(UserInGroup(DOMAIN_ALIAS_RID_ADMINS),True)])); Writeln(Format('Current user is Guest %s', [BoolToStr(UserInGroup(DOMAIN_ALIAS_RID_GUESTS),True)])); Writeln(Format('Current user is Power User %s', [BoolToStr(UserInGroup(DOMAIN_ALIAS_RID_POWER_USERS),True)])); readln; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz