Einzelnen Beitrag anzeigen

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