Einzelnen Beitrag anzeigen

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