AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Feststellen, ob "Als Administrator" ausgeführt
Thema durchsuchen
Ansicht
Themen-Optionen

Feststellen, ob "Als Administrator" ausgeführt

Ein Thema von kwhk · begonnen am 12. Mai 2016 · letzter Beitrag vom 12. Mai 2016
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von kwhk
kwhk

Registriert seit: 25. Mär 2009
Ort: Dresden
168 Beiträge
 
Delphi 10.3 Rio
 
#1

Feststellen, ob "Als Administrator" ausgeführt

  Alt 12. Mai 2016, 12:29
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 ?
Hartmut
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.088 Beiträge
 
Delphi 12 Athens
 
#2

AW: Feststellen, ob "Als Administrator" ausgeführt

  Alt 12. Mai 2016, 13:57
Hier im Forum suchenIsAdmin?

Zitat:
Als Administrator
Und das macht man nicht
  • OK, man kann nach sehen, ob der Benutzeraccount "Administrator" heißt, aber nur weil der so heißt, muß er das nicht sein.
  • Man kann auch gucken, ob er in der Benutzergruppe "Administratoren" ist, aber man kann im dann dennoch viele Rechte weggenommen haben. Und muß zuätzlich prüfen, ob diese Rechte auch aktiv sind. (z.B. durch UAC deaktiviert)
  • Also was du wirklich willst, ist zu prüfen, ob der User-Token zu deiner laufenden Anwendung eine "bestimmte" Berechtigung enthält, welche du eigentlich benötigst.
  • Oder man versucht einfach was zu machen und wenn es nicht geht, dann fehlen Einem wohl die nötigen Rechte.

Man kann garantiert auch den Token eines fremden Programms prüfen.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (12. Mai 2016 um 14:01 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#3

AW: Feststellen, ob "Als Administrator" ausgeführt

  Alt 12. Mai 2016, 14:00
hier http://www.michael-puff.de/Programmi...kel/DACL.shtml steht eigentlich alles wichtige für den Einstieg drin. Wobei die eigentlich wichtige Frage ist, was verstehst Du unter "Administrator".

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von kwhk
kwhk

Registriert seit: 25. Mär 2009
Ort: Dresden
168 Beiträge
 
Delphi 10.3 Rio
 
#4

AW: Feststellen, ob "Als Administrator" ausgeführt

  Alt 12. Mai 2016, 14:45
Ich meine den Sachverhalt, wenn man das Programm mit Als Administrator ausführen startet.
Miniaturansicht angehängter Grafiken
10admin.jpg  
Hartmut
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.088 Beiträge
 
Delphi 12 Athens
 
#5

AW: Feststellen, ob "Als Administrator" ausgeführt

  Alt 12. Mai 2016, 15:01
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.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Feststellen, ob "Als Administrator" ausgeführt

  Alt 12. Mai 2016, 15:38
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.
Der Account interessiert nur sekundär (der Accountname interessiert schon mal gar nicht). Primär wird geprüft, ob man sich in der Gruppe Administrators befindet. Dann ist man ein Administrator.

Es geht also um die Rolle.

Und die fragt man so ab:
Delphi-Quellcode:
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;
(Quelle: http://stackoverflow.com/a/6319521/1744164)

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:
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.
Sauber, sicher und im Ernstfall sogar kommunikativ
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (12. Mai 2016 um 15:56 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#7

AW: Feststellen, ob "Als Administrator" ausgeführt

  Alt 12. Mai 2016, 15:38
  • Also was du wirklich willst, ist zu prüfen, ob der User-Token zu deiner laufenden Anwendung eine "bestimmte" Berechtigung enthält, welche du eigentlich benötigst.
  • Oder man versucht einfach was zu machen und wenn es nicht geht, dann fehlen Einem wohl die nötigen Rechte.
Definitiv den zweiten Ansatz wählen! Hier spart man sich alle umständlichen Checks und wenn die entsprechende API, dann ERROR_ACCESS_DENIED zurückgibt, weiß man eh direkt, wo man dran ist.

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;
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)

Geändert von Zacherl (12. Mai 2016 um 15:42 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.088 Beiträge
 
Delphi 12 Athens
 
#8

AW: Feststellen, ob "Als Administrator" ausgeführt

  Alt 12. Mai 2016, 15:55
Und die fragt man so ab:
Wie in den verlinkten Threads zu lesen, knallt das gern mal bei DomänAdministratoren, wenn man nur lokal prüft.
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.

Und dann gibt es eventuell noch Benutzer mit den nötigen Rechten, die aber keine Administratoren sind.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (12. Mai 2016 um 15:57 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#9

AW: Feststellen, ob "Als Administrator" ausgeführt

  Alt 12. Mai 2016, 16:16
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:
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 ist daran schlecht/ungünstig?
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.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
t.roller
(Gast)

n/a Beiträge
 
#10

AW: Feststellen, ob "Als Administrator" ausgeführt

  Alt 12. Mai 2016, 17:37
Ist ähnlich wie hier:

http://stackoverflow.com/questions/8...us-free-pascal

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.

Geändert von t.roller (12. Mai 2016 um 17:39 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:35 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz