Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi LsaAddAccountRights schlägt fehl (https://www.delphipraxis.net/57007-lsaaddaccountrights-schlaegt-fehl.html)

Luckie 14. Nov 2005 23:01


LsaAddAccountRights schlägt fehl
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich benutze folgende Funktion von Colin Wilson, um Gruppen ein Privileg zu zordnen:
Delphi-Quellcode:
function GrantPrivilege(const Server, user, privilege: string; bRemove: boolean): DWORD;
var
  sid              : PSID;
  strSID           : PWideChar;
  sidSize, sidNameUse: DWORD;
  domainNameSize   : DWORD;
  domainName       : array[0..DNLEN] of char;
  attributes       : TLsaObjectAttributes;
  policyHandle     : LSA_HANDLE;
  lsaComputerName, rightsLsaUnicodeString: TLSAUnicodeStr;
  status           : NTStatus;

begin
  result := 0;
  sidSize := 65536;
  GetMem(sid, sidSize);
  domainNameSize := DNLEN + 1;
  try
    if LookupAccountName(PChar(Server), PChar(user), sid, sidSize, domainName, domainNameSize, sidNameUse) then
    begin
      lsaComputerName := TLsaUnicodeStr.CreateFromStr(Server);
      try
        FillChar(attributes, SizeOf(attributes), 0);
        status := LsaOpenPolicy(lsaComputerName.value, attributes, POLICY_CREATE_ACCOUNT or POLICY_LOOKUP_NAMES, policyHandle);
        if status = STATUS_SUCCESS then
        try
          rightsLsaUnicodeString := TLsaUnicodeStr.CreateFromStr(privilege);
          try
            if bRemove then
              status := LsaRemoveAccountRights(PolicyHandle, sid, False, @rightsLsaUnicodeString.value, 1)
            else
              status := LsaAddAccountRights(PolicyHandle, sid, @rightsLsaUnicodeString.value, 1);

            if status <> STATUS_SUCCESS then
              result := (LsaNtStatusToWinError(status));
          finally
            rightsLsaUnicodeString.Free
          end
        finally
          LsaClose(PolicyHandle)
        end
      finally
        lsaComputerName.Free
      end
    end
  finally
    FreeMem(sid)
  end
end;
aufruf mit:
Delphi-Quellcode:
procedure TForm1.Button3Click(Sender: TObject);
var
  err: DWORD;
begin
  err := GrantPrivilege('hal9000', 'Benutzer', 'SeBackupPrivilege', False);
  if err <> 0 then
    ShowMessage(SysErrorMessage(err));
end;
Die SID und das PolicyHandle sollten gültig sein. Trotzdem bekomme ich als Administrator immer ein:
Zitat:

Ein angegebenes Recht ist nicht vorhanden
zurück. Und ich verstehe ehrlich gesagt nicht warum. Beim Entfernen bekomme ich übrigens die gleiche Fehlermeldung.

Ich habe mal ein Demo-Projekt angehangen, dann könnt ihr es selber mal testen. Der Code muss als Administrator ausgeführt werden, sonst geht es nicht!

Luckie 16. Nov 2005 14:52

Re: LsaAddAccountRights schlägt fehl
 
Ich habe mir überlegt, dass ich dem Admin eventuell erst noch ein Privileg aktivieren muss, bevor er das selber darf. Nur ist die Frage welches?

x000x 16. Nov 2005 21:48

Re: LsaAddAccountRights schlägt fehl
 
Moin moin,

@Luckie:
Also ich habe verzweifelt gesucht, deine funktionen sind auf den ersten Blick genau die gewesen,
wie die von Colin Wilson... nur mit dem Unterschied, dass seine Komponente bei mir
einwandfrei funktioniert, dagegen dein Testprogramm den von dir beschriebenen Fehler verursacht.
Wie gesagt, auf den ersten Blick... Nach ca. 20 Blicken und debuggen ist mir dann doch ein Unterschied aufgefallen.
In der Unit lsaapi.pas von CW sieht der constructor von TLsaUnicodeStr wie folgt aus:
Delphi-Quellcode:
constructor TLsaUnicodeStr.CreateFromStr (const st : string);
var
  len : Integer;
  wst : WideString;
begin
  len := Length (st);
  Value.Length := (len + 0) * sizeof (WideChar);
//  Value.MaximumLength := (GUIDSTR_MAX + 5) * SizeOf (WideChar);
  Value.MaximumLength := (len + 1) * sizeof (WideChar);
  GetMem (Value.buffer, sizeof (WideChar) * (len + 1));
  wst := st;
  lstrcpyw (Value.buffer, PWideChar (wst))
end;
In deinem angehängten Bsp. Source wurde unter anderem folgende Zeilen geändert:
Delphi-Quellcode:
  Value.Length := (len + 1) * sizeof (WideChar);
Zitat:

Zitat von PSDK
Length
Specifies the length, in bytes, of the string pointed to by the Buffer member, not including the terminating null character, if any.

Somit wäre nach meinem Verständnis der Source von CW völlig korrekt. Wenn du also die
korrekte Länge setzt, funktioniert auch dein Bsp. Programm.

Luckie 16. Nov 2005 21:58

Re: LsaAddAccountRights schlägt fehl
 
:firejump: :firejump: :firejump: :firejump: :firejump: :firejump: :firejump: :firejump: :firejump: :firejump: :firejump: :firejump: :firejump: :firejump: :firejump: :firejump: :firejump: :firejump: :firejump: :firejump: :firejump: :firejump:

Was ich sagen wollte: Geil, es geht!!! :love:


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:13 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