![]() |
Abfragen ob Process Adminrechte hat?
Hallo,
Ich habe ein Problem unter Vista ... dort ist man zwar als lokaler Admin eingeloggt allerdings werden Programme nur mit Benutzerrechten gestartet. Da ich Funktionen nutze die Administrator Rechte benötigen hatte ich bisher immer zur Sicherheit abgefragt ob der angemeldete Benutzer Admin Rechte hat. Nun liefert die Abfrage True aber das Programm selbst hat gar keine Adminrechte. Kann man nun irgendwie "sicher" abfragen ob das Programm selbst mit "Administrator Rechten" ausgeführt wird ? Vielen Dank im Vorraus. |
Re: Abfragen ob Process Adminrechte hat?
Kannst du mir mal dein Testprogramm zuschicken (zB per PN). Ich werde mir mal die Vista Preview installieren, welche ich mir bei MSDN runtergeladen habe. Das Problem klingt nämlich interessant.
|
Re: Abfragen ob Process Adminrechte hat?
Hallo Olli,
mit einer Antwort hatte ich gar nich mehr gerechnet :) Also ich verwende bisher folgenden Code zum ermitteln ob der aktuelle Benutzer Administrator Rechte hat:
Delphi-Quellcode:
const
SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5)); SECURITY_BUILTIN_DOMAIN_RID = $00000020; DOMAIN_ALIAS_RID_ADMINS = $00000220; function IsAdmin: Boolean; var hAccessToken: THandle; ptgGroups: PTokenGroups; dwInfoBufferSize: DWORD; psidAdministrators: PSID; x: Integer; bSuccess: BOOL; begin Result := False; bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True, hAccessToken); if not bSuccess then begin if GetLastError = ERROR_NO_TOKEN then bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, hAccessToken); end; if bSuccess then begin GetMem(ptgGroups, 1024); bSuccess := GetTokenInformation(hAccessToken, TokenGroups, ptgGroups, 1024, dwInfoBufferSize); CloseHandle(hAccessToken); if bSuccess then begin AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, psidAdministrators); {$R-} for x := 0 to ptgGroups.GroupCount - 1 do if EqualSid(psidAdministrators, ptgGroups.Groups[x].Sid) then begin Result := True; Break; end; {$R+} FreeSid(psidAdministrators); end; FreeMem(ptgGroups); end; end; Diese Funktion liefert auf allen neueren Vista Versionen mit UAP natürlich "True" da der angemeldete Benutzer Administrator Rechte hat. Was ich noch herausgefunden habe ist das MS es wohl über einen Manifest Eintrag steuert ob das Programm Administrator Rechte benötigt und den Benutzer speziell dann darauf hinweist. Mein Programm kann aber auch unter eingeschränkten Rechten problemlos laufen, wenn ich diese Funktionen in dem Fall nicht durchführe. Deswegen würde ich nun gerne abfragen können welche Rechte das Programm hat und nicht welche Rechte der angemeldete Benutzer hat. |
Re: Abfragen ob Process Adminrechte hat?
Das Problem ist, dass es nun zwei Sicherheits-Token gibt.
(eines mit allen Rechten und ein 'beschnittenes' mit dem fast alle normalen Programme laufen) Siehe ![]() Eine Lösung in Delphi kann ich auf die Schnelle nicht anbieten. |
Re: Abfragen ob Process Adminrechte hat?
Also wenn ich das richtig verstanden habe ist per default das niedrigste Privileg gültig für Programme aber die Frage ist was passiert mit dem Privileg wenn man "Run as Administrator" zum starten des Programms verwendet ... also irgendwie ist das ganz schön komplex :shock:
|
Re: Abfragen ob Process Adminrechte hat?
Ein Dirty-Methode wäre es zu versuchen, in den Systemteil der Registry zu schreiben (oder nich read-only zu öffnen). Wenns funktioniert: Programm hat Adminrechte, wenn nicht User-Rechte.
|
Re: Abfragen ob Process Adminrechte hat?
Zitat:
Die Aussage von IsAdmin() ist immer noch korrekt (Mitglied der lokalen Gruppe der Administratoren). Allerdings ist bisherige Interpretation (lokaler Admin = alle Rechte) nicht zutreffend. Diese Interpretation wahr schon immer falsch (wenn auch hinreichend genau für die meisten Fälle). Allerdings tritt das Problem nun 'dank' Vista auf einem Standardsystem offen zu tage. |
Re: Abfragen ob Process Adminrechte hat?
Your personal bugfix ;)
vorher:
Delphi-Quellcode:
nacher:
if EqualSid(psidAdministrators, ptgGroups.Groups[x].Sid) then
Delphi-Quellcode:
Man muss zusätzlich überprüfen, ob die Gruppe überhaupt für Sicherheitsabfragen relevant ist.
if (SE_GROUP_ENABLED = (ptgGroups.Groups[x].Attributes and SE_GROUP_ENABLED)) and
EqualSid(psidAdministrators, ptgGroups.Groups[x].Sid) then (SE_GROUP_ENABLED = 4) |
Re: Abfragen ob Process Adminrechte hat?
Hey super, das ging ja fix danke :)
Nun hab ich grad kein Vista zur Hand ... aber ich werd das ausprobieren sobald MS die neue Public Beta 2 released hat. Ich hab grad mal nach dem SE_GROUP_ENABLED Flag im MSDN nachgeschlagen das gibt es ja schon seit es NT gibt ... dann brauch ich mir ja keine Sorgen machen das die Abfrage dann auf "älteren" Windows Versionen falsche Ergebnisse liefert. |
Re: Abfragen ob Process Adminrechte hat?
Zitat:
Die Überprüfung ist immer noch 'vereinfacht' (normalerweise müsste man mit der SID einen SD erstellen und mittels AccessCheck gegen das Token prüfen). Wenn man Windows XP voraussetzen kann, dann beschränkt sich die 'korrekte' Abfrage auf:
Delphi-Quellcode:
Wenn man Windows 2000 voraussetzen kann, dann beschränkt sich die 'korrekte' Abfrage auf:
function IsUserAdmin: BOOL;
begin Result := SHTestTokenMembership(THandle(nil), DOMAIN_ALIAS_RID_ADMINS); end;
Delphi-Quellcode:
Wenn man allerdings Windows NT 4.0 unterstützen muss, dann wird's aufwendig (InitializeSecurityDescriptor, SetSecurityDescriptorOwner, SetSecurityDescriptorGroup, InitializeAcl, AddAccessAllowedAce, SetSecurityDescriptorDacl, AccessCheck).
function IsUserAdmin: BOOL;
var SidToCheck: PSID; begin Result := AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, SidToCheck); if Result then begin if not CheckTokenMembership(THandle(nil), SidToCheck, Result) then Result := False; FreeSid(SidToCheck); end; end; |
Re: Abfragen ob Process Adminrechte hat?
Also bis Win2k geh ich auch noch mit ... alle anderen haben sowieso verloren bei mir :)
Aber vielen dank auf jeden Fall nochmal, ich hab mich schon einige Wochen immermal durch irgendwelche Vista UAP(UAC) und Vista tauglichkeits Blogs geforstet aber in keine stand drin dass das SE_GROUP_ENABLED Flag der auschlaggebende Punkt ist. :( |
Re: Abfragen ob Process Adminrechte hat?
Zitat:
|
Re: Abfragen ob Process Adminrechte hat?
Hier ist deine alte Version:
Delphi-Quellcode:
////////////////////////////////////////////////////////////////////////////////
// Procedure : GetAdminSid // Author : NBe // Comment : function GetAdminSid: PSID; const // bekannte SIDs ... (WinNT.h) SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5)); // bekannte RIDs ... (WinNT.h) 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; //////////////////////////////////////////////////////////////////////////////// // Procedure : IsAdmin // Author : NBe // Comment : function IsAdmin: LongBool; var TokenHandle : THandle; ReturnLength : DWORD; TokenInformation : PTokenGroups; AdminSid : PSID; Loop : Integer; begin Result := False; TokenHandle := 0; if OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, TokenHandle) 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 Result := True; Break; end; end; FreeSid(AdminSid); end; finally FreeMemory(TokenInformation); end; finally CloseHandle(TokenHandle); end; end; |
Re: Abfragen ob Process Adminrechte hat?
Zitat:
Ich sehe keine Sinn darin, hier fehlerhaften Code zu posten. Es wäre hilfreicher, wenn sich jemand die Mühe macht und CheckTokenMembership nachprogrammiert (damit Windows NT 4.0 nicht ausgeschossen wird und die Leute verstehen, was die Funktion eigentlich macht). |
Re: Abfragen ob Process Adminrechte hat?
@NicoDE:
So gerade die aktuelle Public Beta installiert und getestet ... das klappt jetzt wunderbar. Hab deine Win2k Version genommen. Vielen Dank nochmal :) |
Re: Abfragen ob Process Adminrechte hat?
Zitat:
|
Re: Abfragen ob Process Adminrechte hat?
Zitat:
|
Re: Abfragen ob Process Adminrechte hat?
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Zum Anhang: Bei einem auf diese Art gestarteten Programm muss IsUserAdmin() False liefern (wenn man die Aussage als 'der Benutzer hat lokale administrative Rechte' interpretieren möchte). |
Re: Abfragen ob Process Adminrechte hat?
Könntest du deine obige Funktien entsprechend anpassen, da ich kein Vista zum Testen habe?
|
Re: Abfragen ob Process Adminrechte hat?
Zitat:
|
Re: Abfragen ob Process Adminrechte hat?
Liste der Anhänge anzeigen (Anzahl: 1)
@Nico:
Dat is aus deiner (alten) Variante heraus entstanden ... was genau würdest du jetzt noch ändern wollen? kann's grad nich testen, aber dieses SE_GROUP_ENABLED hab'sch erstma reingemacht :roll:
Code:
For Loop := 0 to TokenInformation^.GroupCount - 1 do
If [color=#ff0000](TokenInformation^.Groups[Loop].Attributes and SE_GROUP_ENABLED <> 0)[/color] and EqualSid(TokenInformation^.Groups[Loop].Sid, AdminSid) Then Begin
Delphi-Quellcode:
Aufrufen tu ich's einfach ma so:
//ganze Unit siehe Anhang
Function CheckForAdmin: Boolean; Const SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5)); SECURITY_BUILTIN_DOMAIN_RID = $00000020; DOMAIN_ALIAS_RID_ADMINS = $00000220; Var TokenHandle: THandle; ReturnLength: LongWord; TokenInformation: PTokenGroups; AdminSid: PSID; Loop: Integer; AdminCheckForm: TAdminCheckForm; Begin Result := False; TokenHandle := 0; TokenInformation := nil; If OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, TokenHandle) Then Try GetTokenInformation(TokenHandle, TokenGroups, nil, 0, ReturnLength); TokenInformation := GetMemory(ReturnLength); If (TokenInformation <> nil) and GetTokenInformation(TokenHandle, TokenGroups, TokenInformation, ReturnLength, ReturnLength) Then Begin AdminSid := nil; AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, AdminSid); For Loop := 0 to TokenInformation^.GroupCount - 1 do If ((TokenInformation^.Groups[Loop].Attributes and SE_GROUP_ENABLED) = SE_GROUP_ENABLED) and EqualSid(TokenInformation^.Groups[Loop].Sid, AdminSid) Then Begin Result := True; Break; End; FreeSid(AdminSid); End; Finally FreeMemory(TokenInformation); CloseHandle(TokenHandle); End; If not Result Then Begin AdminCheckForm := TAdminCheckForm.Create(nil); AdminCheckForm.ShowModal; AdminCheckForm.Free; End; End;
Delphi-Quellcode:
Program ...;
Uses DataRescue_AdminCheck, ...; Begin ... If not CheckForAdmin Then Exit; ... End. |
Re: Abfragen ob Process Adminrechte hat?
Ich hätte die Funktion IsAdmin oder IsRunningUnderAdminPrivileges genannt.
|
Re: Abfragen ob Process Adminrechte hat?
Aber nur die "neue" Version (jetzt wo man och noch zwischen 'nem Benutzer und seinen Rechten unterscheiden muß -.-'' ).
Bei der "alten" Variante sollte daß IsAdmin doch noch stimmen? |
Re: Abfragen ob Process Adminrechte hat?
Zitat:
|
Re: Abfragen ob Process Adminrechte hat?
Och, laß dir Zeit ... bis XP läuft es anscheinend ja ganz gut und Vista gibt's "noch" nicht.
Wollt daß nur solange noch "beheben", wie ich wenigstens ä bissl in der Materie drin bin ... glaub nicht, daß ich sowas so schnell nochmal machen/gebrauchen werde ._. |
Re: Abfragen ob Process Adminrechte hat?
Liste der Anhänge anzeigen (Anzahl: 1)
Hab meine integrierte Version nochmal auf deine zurückgeführt, :angel:
sodaß jetzt erstma was (hoffentlich) "Funktionierendes" existiert.
Delphi-Quellcode:
Und da ich's grad bemerkt hatte ... in meiner Unit werden jetzt an CreateProcessWithLogon auch das Arbeitsverzeichnis und die Parameterliste mit übergeben (gut daß ich da jetzt doch nochmal reingesehen hab ._.)
////////////////////////////////////////////////////////////////////////////////
// Procedure : HasAdminPrivileges // Author : NBe // Comment : function HasAdminPrivileges: LongBool; const // bekannte SIDs ... (WinNT.h) SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5)); // bekannte RIDs ... (WinNT.h) SECURITY_BUILTIN_DOMAIN_RID: DWORD = $00000020; DOMAIN_ALIAS_RID_ADMINS: DWORD = $00000220; SE_GROUP_ENABLED: DWORD = $00000004; var TokenHandle : THandle; ReturnLength : DWORD; TokenInformation : PTokenGroups; AdminSid : PSID; Loop : Integer; begin Result := False; TokenHandle := 0; TokenInformation := nil; AdminSid := nil; if OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, TokenHandle) then try ReturnLength := 0; GetTokenInformation(TokenHandle, TokenGroups, nil, 0, ReturnLength); TokenInformation := GetMemory(ReturnLength); if Assigned(TokenInformation) and GetTokenInformation(TokenHandle, TokenGroups, TokenInformation, ReturnLength, ReturnLength) then begin AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, AdminSid); for Loop := 0 to TokenInformation^.GroupCount - 1 do begin if (SE_GROUP_ENABLED = (TokenInformation^.Groups[Loop].Attributes and SE_GROUP_ENABLED)) and EqualSid(TokenInformation^.Groups[Loop].Sid, AdminSid) then begin Result := True; Break; end; end; FreeSid(AdminSid); AdminSid := nil; end; finally FreeSid(AdminSid); FreeMemory(TokenInformation); CloseHandle(TokenHandle); end; end; CheckForAdminPrivileges sorgt also dafür, daß das Programm mit Admin-Rechten gestartet wird.
Delphi-Quellcode:
(ich glaub hier würde sich ein TriState-Result besser machen :oops: ... aber erstmal sehn was Nico draus macht)
If CheckForAdminPrivileges Then Begin
// Programm gestartet End Else Begin // konnte nicht mit Admin-Rechten gestartet werden, // // und/oder eine andere Instanz des Programms wurde // mit Admin-Rechten gestartet End; |
Re: Abfragen ob Process Adminrechte hat?
Ich stehe gerade vor dem gleichen Problem, rauszufinden, mit welchen Rechten der Prozess jetzt "tatsächlich" läuft. Alle hier vorgestellten Methoden funktionieren leider nicht, auch nicht die Win2K Variante. Der Rückgabewert von CheckTokenMembership ist dann true, wenn der Check funktioniert hat. NICHT, wenn die Bedingung zutrifft. Man muss dafür als 3. Parameter einen Bool Wert übergeben und diesen Auswerten. Mit der aktuellen Methode liefert bei mir der Check nämlich auch bei einem eingeschränkten Benutzerkonto "true" zurück, was aber falsch ist :(
|
Re: Abfragen ob Process Adminrechte hat?
Zitat:
|
Re: Abfragen ob Process Adminrechte hat?
Sorry, da hab ich mich verguckt, stimmt. Leider funktioniert das bei mir trotzdem nicht :(
|
Re: Abfragen ob Process Adminrechte hat?
Zitat:
Quelltext? Was genau geht nicht? |
Re: Abfragen ob Process Adminrechte hat?
Ich dachte eigentlich nicht, dass du Dir die Mühe machen würdest, hier nochmal genauer drauf einzugehen, da das Thema ja schon ne Weile her ist, darum hab ich das nicht gleich gepostet. Aber um so besser:
Delphi 6 Ich benutze den Code aus deiner Unit. Um genauer zu sein, nur die Funktion CheckForAdminPrivileges; Beim 2. Durchlauf der "For i := 0 to TokenInformation^.GroupCount - 1 do" Schleife bekomme ich direkt in der 1. Zeile folgendes: --------------------------- Benachrichtigung über Debugger-Exception --------------------------- Im Projekt FEX.exe ist eine Exception der Klasse ERangeError aufgetreten. Meldung: 'Fehler bei Bereichsprüfung'. Prozeß wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen. Beim Debuggen ist mir aber nichts weiter aufgefallen. Alle Variablen, die verwendet werden, sind definiert. |
Re: Abfragen ob Process Adminrechte hat?
Der einfachste Lösung ist das Deaktivieren der Bereichsüberprüfung in den Projektoptionen.
(liegt an der Art und Weise wie TTokenGroups deklariert wurde) |
Re: Abfragen ob Process Adminrechte hat?
Ich hab das ganze jetzt schon anders umgangen, so dass keine Exception mehr auftritt. Das Problem ist nach wie vor das selbe. Das liegt einfach daran, dass Vista Programme, wenn nicht anders angegeben, automatisch im eingeschränkten Kontext laufen lässt. Hab eben das Stichwort "manifest file" in diesem Zusammenhang gelesen, vielleicht hilft mir das weiter. Aber danke für die Mühen :-D
|
Re: Abfragen ob Process Adminrechte hat?
Zitat:
|
Re: Abfragen ob Process Adminrechte hat?
Eventuell noch was zu den Rechten:
![]() |
Re: Abfragen ob Process Adminrechte hat?
Zitat:
|
Re: Abfragen ob Process Adminrechte hat?
Zitat:
|
AW: Abfragen ob Process Adminrechte hat?
hallo
ich wollte die funktion auch verwenden, jedoch findet meine IDE "SE_GROUP_ENABLED" nicht. Welche unit bzw. api muss ich denn bei uses eintragen? Habe schon google befragt, aber nichts richtiges gefunden. |
AW: Abfragen ob Process Adminrechte hat?
Das sieht nach einer Konstanten aus. Eine schnelle Suche mit Google bringt Klarheit.
|
AW: Abfragen ob Process Adminrechte hat?
Delphi-Quellcode:
gruss
const
SE_GROUP_ENABLED = 4; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:32 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