AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) C++ Administratorrechte anfordern (Elevation/Impersonation ?)
Thema durchsuchen
Ansicht
Themen-Optionen

Administratorrechte anfordern (Elevation/Impersonation ?)

Ein Thema von OregonGhost · begonnen am 30. Mai 2007 · letzter Beitrag vom 17. Nov 2016
Antwort Antwort
Seite 1 von 2  1 2      
OregonGhost

Registriert seit: 8. Jun 2002
Ort: Lübeck
1.216 Beiträge
 
Delphi 3 Professional
 
#1

Administratorrechte anfordern (Elevation/Impersonation ?)

  Alt 30. Mai 2007, 15:32
Moin,
folgendes Szenario. Ich habe einen Dienst, nennen wir ihn Dienst.exe. Zum Installieren oder Deinstallieren benötigt man Administratorrechte (oder nicht?). Das ist bis hierhin unter Windows XP oder 2003 nicht weiter problematisch, unter Vista hingegen startet man bekanntermaßen ein Programm auch dann ohne Administratorrechte, wenn man als Administrator angemeldet ist. Wenn jetzt also ein Benutzer
Code:
Dienst.exe -install
bzw.
Dienst.exe -uninstall
aufruft, und nur dann, soll das Programm als Administrator ausgeführt werden. Vielleicht habe ich hier und in Google nur die falschen Suchworte benutzt, aber ich habe bislang nur die folgende Möglichkeit gefunden:

Über ein Vista-Manifest highestAvailablePrivileges anfordern. Das bedeutet, dass das Programm, von einem Benutzer gestartet, von diesem Administratorrechte anfordert, ist das richtig? Also als Administrator muss man einmal auf Bestätigen klicken, als normaler Benutzer muss man Benutzername/Passwort eingeben? Oder startet das Programm dann als normaler Benutzer gar nicht oder mit niedrigeren Rechten? Und was passiert nun, wenn der SCM das Programm als Dienst starten möchte? Hat es dann eventuell höhere Rechte als notwendig (SYSTEM-Account)? Mir war so, als hätte ich auch von der Möglichkeit gelesen, einem Dienst so wenig Rechte wie möglich (aber so viel wie nötig) zuzuweisen.

Gibt es alternativ die Möglichkeit, die Rechte erst später anzufordern, nämlich dann, wenn sie benötigt werden, und das am besten so, dass es unter XP auch funktioniert (wenn das dort überhaupt möglich ist)? Das wäre mir nämlich eigentlich lieber. Ich habe von dem Stichwort Impersonation gehört, aber konnte nicht recht eine schöne Erklärung dazu finden, bzw. ob das der richtige Weg ist. Sachdienliche Hinweise werden mit Freude entgegengenommen, auch, ob eventuell eine komplett andere Vorgehensweise günstiger ist.
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
  Mit Zitat antworten Zitat
OregonGhost

Registriert seit: 8. Jun 2002
Ort: Lübeck
1.216 Beiträge
 
Delphi 3 Professional
 
#2

Re: Administratorrechte anfordern (Elevation/Impersonation ?

  Alt 1. Jun 2007, 10:46
Hmm, ausnahmsweise pushe ich mal meinen Beitrag - da muss es doch jemanden geben, der sich damit auskennt
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
  Mit Zitat antworten Zitat
NicoDE
(Gast)

n/a Beiträge
 
#3

Re: Administratorrechte anfordern (Elevation/Impersonation ?

  Alt 1. Jun 2007, 11:07
Zitat von OregonGhost:
Ich habe einen Dienst, nennen wir ihn Dienst.exe. Zum Installieren oder Deinstallieren benötigt man Administratorrechte (oder nicht?). Das ist bis hierhin unter Windows XP oder 2003 nicht weiter problematisch, unter Vista hingegen startet man bekanntermaßen ein Programm auch dann ohne Administratorrechte, wenn man als Administrator angemeldet ist.
Auch unter Windows XP konnte man ein Programm ohne administratives Token starten ('Ausführen als...' und die CheckBox aktivieren).

Zitat von OregonGhost:
Wenn jetzt also ein Benutzer
Code:
Dienst.exe -install
bzw.
Dienst.exe -uninstall
aufruft, und nur dann, soll das Programm als Administrator ausgeführt werden.
Ich gehe mal davon aus, dass die Datei nur von Administratoren (Install/Uninstall) und dem System (SCM) verwendet wird.
Ich sehe also keinen Grund, warum das 'Programm' von einem unterpriviligierten Benutzer verwendet werden sollte.
Zitat von OregonGhost:
Über ein Vista-Manifest highestAvailablePrivileges anfordern. Das bedeutet, dass das Programm, von einem Benutzer gestartet, von diesem Administratorrechte anfordert, ist das richtig? Also als Administrator muss man einmal auf Bestätigen klicken, als normaler Benutzer muss man Benutzername/Passwort eingeben? Oder startet das Programm dann als normaler Benutzer gar nicht oder mit niedrigeren Rechten?
[asInvoker(Standard)]
Admin = kein UAC-Dialog, eingeschränktes Token
Users = kein UAC-Dialog
[highestAvailable]
Admin = UAC-Dialog, komplettes Token
Users = kein UAC-Dialog
[requireAdministrator]
Admin = UAC-Dialog, komplettes Token
Users = UAC-Dialog mit Username/Passwort für Admin-Account

requireAdministrator wäre wohl das gesuchte.

Zitat von OregonGhost:
Und was passiert nun, wenn der SCM das Programm als Dienst starten möchte? Hat es dann eventuell höhere Rechte als notwendig (SYSTEM-Account)? Mir war so, als hätte ich auch von der Möglichkeit gelesen, einem Dienst so wenig Rechte wie möglich (aber so viel wie nötig) zuzuweisen.
In Versionen vor Windows Vista haben System-Dienste grundsätzlich alle Rechte. Erst in Vista kann man dem SCM (mittels API konfigurierbar) mitteilen, welche Rechte der Dienst wirklich braucht (bei Dienst-DLLs werden die Rechte der Gruppe zusammengesetzt).

Zitat von OregonGhost:
Gibt es alternativ die Möglichkeit, die Rechte erst später anzufordern, nämlich dann, wenn sie benötigt werden, und das am besten so, dass es unter XP auch funktioniert (wenn das dort überhaupt möglich ist)?
Ein laufender Prozess kann sein eingeschränktes Token nicht in ein komplettes Token 'umwandeln' lassen. Der Prozess muss also neu gestartet werden (z.B. mit ShellExecute und 'runas' als Verb - was bedeutet, dass das Programm anschließend mit administrativen Rechten läuft, um die nötigen Dialoge kümmert sich Windows).
  Mit Zitat antworten Zitat
OregonGhost

Registriert seit: 8. Jun 2002
Ort: Lübeck
1.216 Beiträge
 
Delphi 3 Professional
 
#4

Re: Administratorrechte anfordern (Elevation/Impersonation ?

  Alt 1. Jun 2007, 11:29
Danke, das hilft mir schon sehr weiter. Vermutlich hast du recht, eigentlich besteht keine Notwendigkeit, das Programm von einem normalen Benutzer ausführen zu lassen. Was mir noch nicht ganz klar ist: Ich bekomme also mit einem requireAdministrator im Manifest unter Vista das gewünschte Verhalten - gibt es eine direkt vergleichbare Möglichkeit unter XP, oder muss dort der Benutzer schon vorher als Administrator angemeldet sein bzw. das Programm explizit als Administrator ausführen? Vermutlich ist das nicht so wichtig, weil es keine Katastrophe wäre, zum Administrieren eines Rechners als Administrator eingeloggt zu sein, aber man weiß ja nie...
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
  Mit Zitat antworten Zitat
NicoDE
(Gast)

n/a Beiträge
 
#5

Re: Administratorrechte anfordern (Elevation/Impersonation ?

  Alt 1. Jun 2007, 11:39
Zitat von OregonGhost:
Was mir noch nicht ganz klar ist: Ich bekomme also mit einem requireAdministrator im Manifest unter Vista das gewünschte Verhalten - gibt es eine direkt vergleichbare Möglichkeit unter XP, [...]
Gibt es nicht. Aber man kann sowas programmieren (hat nichts mit XP oder Vista zu tun). Zum Beispiel: gleich am Anfang der DPR "if not IsUserAnAdmin() and not IsRunningAsLocalSystem() then" - in diesem Falle könnte man den Benutzer auf die notwendigen Rechte hinweisen und/oder das Programm mit den selben Parametern als Admin starten (runas).

ps: das hat aber eher mit Benutzerfreundlichkeit zu tun, die Installation als nicht-Admin würde ohnehin fehlschlagen.
  Mit Zitat antworten Zitat
OregonGhost

Registriert seit: 8. Jun 2002
Ort: Lübeck
1.216 Beiträge
 
Delphi 3 Professional
 
#6

Re: Administratorrechte anfordern (Elevation/Impersonation ?

  Alt 1. Jun 2007, 11:46
So, jetzt habe ich einfach mal das Manifest eingebunden und das funktioniert soweit. Also PowerShell geöffnet, Dienst.exe -install aufgerufen, UAC meldet sich mit einem nichtidentifizierten Programm (das wird erst richtig schön, wenn es signiert ist, oder?), ich bestätige... und es öffnet sich eine neue Konsole, gibt was aus und schließt die Konsole wieder. Plöd, man sieht ja gar nicht, was das Ding ausgibt, weil es zu schnell wieder zu ist und überhaupt lieber in die ursprüngliche Shell gehört. Ich schätze, da gibt es keine schöne Möglichkeit drumherum, außer indem es sich mit runas noch einmal selbst startet, oder? Aber ich dachte, um genau so eine Notwendigkeit zu vermeiden, gibt es jetzt diese Manifest-UAC-Geschichte...^^

Edit: Gerade gelesen unter IsUserAnAdmin():
Zitat:
Note This function is available through Microsoft Windows XP Service Pack 2 (SP2) and Windows Server 2003. It might be altered or unavailable in subsequent versions of Windows.
*seufz*
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
  Mit Zitat antworten Zitat
NicoDE
(Gast)

n/a Beiträge
 
#7

Re: Administratorrechte anfordern (Elevation/Impersonation ?

  Alt 1. Jun 2007, 11:55
Zitat von OregonGhost:
*seufz*
Kann man nachbauen (natürlich Vista-kompatibel, da viele IsAdmin-Funktionen eingeschränkte Token fälschlicherweise als Admin-Token erkennen).
Ich schau später mal, ob ich meine Wrapper-Funktionen noch finde
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#8

Re: Administratorrechte anfordern (Elevation/Impersonation ?

  Alt 1. Jun 2007, 12:05
Meinst du die:
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;
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
OregonGhost

Registriert seit: 8. Jun 2002
Ort: Lübeck
1.216 Beiträge
 
Delphi 3 Professional
 
#9

Re: Administratorrechte anfordern (Elevation/Impersonation ?

  Alt 1. Jun 2007, 12:15
Klingt toll ^^

Ich hab das mit ShellExecute und so jetzt mal getestet - das Programm mit Administratorrechten wird dann ja trotzdem nicht in derselben Konsole gestartet, wie unangenehm. Nun gibt es natürlich nicht viele Ausgaben im Normalfall, aber im Fehlerfall eben doch. Bei der ShellExecute-Geschichte seh ich gar keine Ausgabe, bei der requireAdministrator-Geschichte ist sie in einer eigenen Konsole, die sich sofort wieder schließt, da hast du nicht zufällig auch noch nen Tipp? In einer bereits als Administrator gestarteten PowerShell bekomme ich alle Ausgaben.

Und dass ich beim Linken die Warnung
Code:
1>.\VistaAdmin.manifest : manifest authoring warning 81010002: Unrecognized Element "requestedPrivileges" in namespace "urn:schemas-microsoft-com:asm.v3".
bekomme, klingt so, als ob da noch was nicht stimmt, aber Vista liest das Ding trotzdem richtig aus.

Huch, roter Kasten, danke für den Code, Luckie. Damit kann ich schonmal gezielter Fehlermeldungen ausgeben als auf ERROR_ACCESS_DENIED zu warten. Aber irgendwie schmeckt mir die ganze Geschichte mit entweder fehlenden bzw. an der falschen Stelle stehenden Ausgaben, oder alternativ ohne UAC nicht so richtig. Naja, mal schauen.

Edit: Ich habe den Code jetzt ausprobiert. Wenn ich das richtig sehe, gibt der Code ja nur an, ob man in der Gruppe Administratoren ist... Nicht, ob man Admin-Rechte hat. Da muss ich wohl noch etwas suchen, oder hoffen, dass NicoDE seine Wrapper-Funktionen findet

Und noch ein Edit: In Absprache mit meinem Kollegen ist es wohl besser, wenn wir auf UAC verzichten und stattdessen bei fehlenden Rechten nur eine Fehlermeldung ausgeben, weil man mit UAC ja eventuelle Fehlermeldungen nicht oder nur ungünstig lesen kann. Also wäre eine IsAdmin-Funktion inklusive Vista-Unterstützung das Beste (wobei ich zurzeit einfach schaue, ob das Öffnen des SCM mit ERROR_ACCESS_DENIED fehlschlägt, nicht schön, aber reicht im Endeffekt erstmal).
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
  Mit Zitat antworten Zitat
NicoDE
(Gast)

n/a Beiträge
 
#10

Re: Administratorrechte anfordern (Elevation/Impersonation ?

  Alt 1. Jun 2007, 14:29
Zitat von OregonGhost:
oder hoffen, dass NicoDE seine Wrapper-Funktionen findet
Die Hoffnung stirbt zuletzt
(sind genauso zu verwenden wie die API-Funktionen - die Fallbacks dürften auch das gleiche machen wie die jeweilige API *g*)
Delphi-Quellcode:
unit TokenTools;

interface

uses
  Windows;

function CheckTokenMembership(TokenHandle: THandle; SidToCheck: PSID;
  out IsMember: BOOL): BOOL; stdcall;
function SHTestTokenMembership(hToken: THandle; ulRID: ULONG): BOOL; stdcall;
function IsUserAnAdmin(): BOOL; stdcall;

implementation

function GetAdvApi32Lib(): HMODULE;
const
  ModuleName = 'ADVAPI32';
{$WRITEABLECONST ON}
const
  ModuleHandle: HMODULE = HMODULE(nil);
{$WRITEABLECONST OFF}
begin
  Result := ModuleHandle;
  if Result = HMODULE(nil) then
  begin
    Result := LoadLibrary(ModuleName);
    if Result <> HMODULE(nil) then
      ModuleHandle := Result;
  end;
end;

function CheckTokenMembership(TokenHandle: THandle; SidToCheck: PSID;
  out IsMember: BOOL): BOOL;
type
  TFNCheckTokenMembership = function(TokenHandle: THandle; SidToCheck: PSID;
    out IsMember: BOOL): BOOL; stdcall;
{$WRITEABLECONST ON}
const
  Initialized: Integer = 0;
  RealApiFunc: TFNCheckTokenMembership = nil;
{$WRITEABLECONST OFF}
type
  TAceHeader = packed record
    AceType : Byte;
    AceFlags: Byte;
    AceSize : Word;
  end;
  TAccessAllowedAce = packed record
    Header : TAceHeader;
    Mask : ACCESS_MASK;
    SidStart: DWORD;
  end;
const
  ACL_REVISION = 2;
  DesiredAccess = 1;
  GenericMapping: TGenericMapping = (
    GenericRead : STANDARD_RIGHTS_READ;
    GenericWrite : STANDARD_RIGHTS_WRITE;
    GenericExecute: STANDARD_RIGHTS_EXECUTE;
    GenericAll : STANDARD_RIGHTS_ALL
  );
var
  ClientToken: THandle;
  ProcessToken: THandle;
  SecurityDescriptorSize: Cardinal;
  SecurityDescriptor: PSecurityDescriptor;
  Dacl: PACL;
  PrivilegeSetBufferSize: ULONG;
  PrivilegeSetBuffer: packed record
    PrivilegeSet: TPrivilegeSet;
    Buffer: array [0..2] of TLUIDAndAttributes;
  end;
  GrantedAccess: ACCESS_MASK;
  AccessStatus: BOOL;
begin
  if Initialized = 0 then
  begin
    RealApiFunc := TFNCheckTokenMembership(
      GetProcAddress(GetAdvApi32Lib(), 'CheckTokenMembership'));
    InterlockedIncrement(Initialized);
  end;
  if Assigned(RealApiFunc) then
    Result := RealApiFunc(TokenHandle, SidToCheck, IsMember)
  else
  begin
    Result := False;
    IsMember := False;
    ClientToken := THandle(nil);
    try
      if TokenHandle <> THandle(nil) then
        ClientToken := TokenHandle
      else if not OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, False,
        ClientToken) then
      begin
        ClientToken := THandle(nil);
        if GetLastError() = ERROR_NO_TOKEN then
        begin
          if OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY or
            TOKEN_DUPLICATE, ProcessToken) then
          try
            if not DuplicateToken(ProcessToken, SecurityImpersonation,
              @ClientToken) then
            begin
              ClientToken := THandle(nil);
            end;
          finally
            CloseHandle(ProcessToken);
          end;
        end;
      end;
      if ClientToken <> THandle(nil) then
      begin
        SecurityDescriptorSize := SizeOf(TSecurityDescriptor) +
          SizeOf(TAccessAllowedAce) + SizeOf(TACL) +
          3 * GetLengthSid(SidToCheck);
        SecurityDescriptor := PSecurityDescriptor(
          LocalAlloc(LMEM_ZEROINIT, SecurityDescriptorSize));
        if SecurityDescriptor <> nil then
        try
          if InitializeSecurityDescriptor(SecurityDescriptor,
            SECURITY_DESCRIPTOR_REVISION) then
          begin
            if SetSecurityDescriptorOwner(SecurityDescriptor, SidToCheck,
              False) then
            begin
              if SetSecurityDescriptorGroup(SecurityDescriptor, SidToCheck,
                False) then
              begin
                Dacl := PACL(SecurityDescriptor);
                Inc(PSecurityDescriptor(Dacl));
                if InitializeAcl(Dacl^,
                  SecurityDescriptorSize - SizeOf(TSecurityDescriptor),
                  ACL_REVISION) then
                begin
                  if AddAccessAllowedAce(Dacl^, ACL_REVISION, DesiredAccess,
                    SidToCheck) then
                  begin
                    if SetSecurityDescriptorDacl(SecurityDescriptor, True, Dacl,
                      False) then
                    begin
                      PrivilegeSetBufferSize := SizeOf(PrivilegeSetBuffer);
                      Result := AccessCheck(SecurityDescriptor, ClientToken,
                        DesiredAccess, GenericMapping,
                        PrivilegeSetBuffer.PrivilegeSet, PrivilegeSetBufferSize,
                        GrantedAccess, AccessStatus);
                      if Result then
                        IsMember := AccessStatus and
                          (GrantedAccess = DesiredAccess);
                    end;
                  end;
                end;
              end;
            end;
          end;
        finally
          LocalFree(HLOCAL(SecurityDescriptor));
        end;
      end;
    finally
      if (ClientToken <> THandle(nil)) and
        (ClientToken <> TokenHandle) then
      begin
        CloseHandle(ClientToken);
      end;
    end;
  end;
end;

function GetShell32Lib(): HMODULE;
const
  ModuleName = 'SHELL32';
{$WRITEABLECONST ON}
const
  ModuleHandle: HMODULE = HMODULE(nil);
{$WRITEABLECONST OFF}
begin
  Result := ModuleHandle;
  if Result = HMODULE(nil) then
  begin
    Result := LoadLibrary(ModuleName);
    if Result <> HMODULE(nil) then
      ModuleHandle := Result;
  end;
end;

function SHTestTokenMembership(hToken: THandle; ulRID: ULONG): BOOL; stdcall;
type
  TFNSHTestTokenMembership = function(hToken: THandle; ulRID: ULONG): BOOL; stdcall;
{$WRITEABLECONST ON}
const
  Initialized: Integer = 0;
  RealApiFunc: TFNSHTestTokenMembership = nil;
{$WRITEABLECONST OFF}
const
  SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
  SECURITY_BUILTIN_DOMAIN_RID = $00000020;
var
  SidToCheck: PSID;
begin
  if Initialized = 0 then
  begin
    RealApiFunc := TFNSHTestTokenMembership(
      GetProcAddress(GetShell32Lib(), 'SHTestTokenMembership'));
    InterlockedIncrement(Initialized);
  end;
  if Assigned(RealApiFunc) then
    Result := RealApiFunc(hToken, ulRID)
  else
  begin
    Result := AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
      SECURITY_BUILTIN_DOMAIN_RID, ulRID, 0, 0, 0, 0, 0, 0, SidToCheck);
    if Result then
    try
      if not CheckTokenMembership(THandle(nil), SidToCheck, Result) then
        Result := False;
    finally
      FreeSid(SidToCheck);
    end;
  end;
end;

function IsUserAnAdmin(): BOOL;
const
  DOMAIN_ALIAS_RID_ADMINS = $00000220;
type
  TFNIsUserAnAdmin = function(): BOOL; stdcall;
{$WRITEABLECONST ON}
const
  Initialized: Integer = 0;
  RealApiFunc: TFNIsUserAnAdmin = nil;
{$WRITEABLECONST OFF}
begin
  if Initialized = 0 then
  begin
    RealApiFunc := TFNIsUserAnAdmin(
      GetProcAddress(GetShell32Lib(), 'IsUserAnAdmin'));
    InterlockedIncrement(Initialized);
  end;
  if Assigned(RealApiFunc) then
    Result := RealApiFunc()
  else
    Result := SHTestTokenMembership(THandle(nil), DOMAIN_ALIAS_RID_ADMINS);
end;

end.
ps: Die von Luckie kopierte IsAdmin-Funktion enthält den klassischen Fehler (es wurde vergessen zu prüfen, ob die aktuelle Sid überhaupt im Token aktiviert ist).
pps: upz, da war aber noch nen blöder Fehler drin *g*
  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 17:30 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