Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi WinAPI Problem mit Rechten setzen in der Registry (https://www.delphipraxis.net/82884-winapi-problem-mit-rechten-setzen-der-registry.html)

RWarnecke 21. Dez 2006 10:10


WinAPI Problem mit Rechten setzen in der Registry
 
Hallo,

ich habe mir diesen Beitrag genommen. Das funktioniert auch sehr gut. Nun möchte ich aber keinen Registry-Key erstellen sondern einen vorhandenen öffnen und dort einen Wert löschen. Mit dem User, womit ich das Programm ausführe, hat nur Lese-Rechte auf den Schlüssel.

Der Code ist folgender :
Delphi-Quellcode:
type
  TAccessMode = (
    NOT_USED_ACCESS,
    GRANT_ACCESS,
    SET_ACCESS,
    DENY_ACCESS,
    REVOKE_ACCESS,
    SET_AUDIT_SUCCESS,
    SET_AUDIT_FAILURE
  );

type
  PObjectsAndSid = ^TObjectsAndSid;
  TObjectsAndSid = record
    ObjectsPresent: DWORD;
    ObjectTypeGuid: TGUID;
    InheritedObjectTypeGuid: TGUID;
    pSid: PSID;
  end;

type

  TSeObjectType = (
    SE_UNKNOWN_OBJECT_TYPE,
    SE_FILE_OBJECT,
    SE_SERVICE,
    SE_PRINTER,
    SE_REGISTRY_KEY,
    SE_LMSHARE,
    SE_KERNEL_OBJECT,
    SE_WINDOW_OBJECT,
    SE_DS_OBJECT,
    SE_DS_OBJECT_ALL,
    SE_PROVIDER_DEFINED_OBJECT,
    SE_WMIGUID_OBJECT
  );
  PObjectsAndNameA = ^TObjectsAndNameA;
  TObjectsAndNameA = record
    ObjectsPresent: DWORD;
    ObjectType: TSeObjectType;
    ObjectTypeName: PAnsiChar;
    InheritedObjectTypeName: PAnsiChar;
    ptstrName: PAnsiChar;
  end;

  PObjectsAndNameW = ^TObjectsAndNameW;
  TObjectsAndNameW = record
    ObjectsPresent: DWORD;
    ObjectType: TSeObjectType;
    ObjectTypeName: PWideChar;
    InheritedObjectTypeName: PWideChar;
    ptstrName: PWideChar;
  end;
  PObjectsAndName = ^TObjectsAndName;
  TObjectsAndName = TObjectsAndNameA;

type
  TMultipleTrusteeOperation = (
    NO_MULTIPLE_TRUSTEE,
    TRUSTEE_IS_IMPERSONATE
  );

  TTrusteeForm = (
    TRUSTEE_IS_SID,
    TRUSTEE_IS_NAME,
    TRUSTEE_BAD_FORM,
    TRUSTEE_IS_OBJECTS_AND_SID,
    TRUSTEE_IS_OBJECTS_AND_NAME
  );

  TTrusteeType = (
    TRUSTEE_IS_UNKNOWN,
    TRUSTEE_IS_USER,
    TRUSTEE_IS_GROUP,
    TRUSTEE_IS_DOMAIN,
    TRUSTEE_IS_ALIAS,
    TRUSTEE_IS_WELL_KNOWN_GROUP,
    TRUSTEE_IS_DELETED,
    TRUSTEE_IS_INVALID,
    TRUSTEE_IS_COMPUTER
  );
  PTrusteeA = ^TTrusteeA;
  TTrusteeA = packed record
    pMultipleTrustee: PTrusteeA;
    MultipleTrusteeOperation: TMultipleTrusteeOperation;
    TrusteeForm: TTrusteeForm;
    TrusteeType: TTrusteeType;
    case TTrusteeForm of
      TRUSTEE_IS_SID: (
        pSid: PSID);
      TRUSTEE_IS_OBJECTS_AND_SID: (
        pObjectsAndSid: PObjectsAndSid);
      TRUSTEE_IS_OBJECTS_AND_NAME: (
        pObjectsAndName: PObjectsAndNameA);
   { else }
      TRUSTEE_IS_NAME, TRUSTEE_BAD_FORM: (
        ptstrName: PAnsiChar);
   { end; }
  end;
  PTrusteeW = ^TTrusteeW;
  TTrusteeW = packed record
    pMultipleTrustee: PTrusteeW;
    MultipleTrusteeOperation: TMultipleTrusteeOperation;
    TrusteeForm: TTrusteeForm;
    TrusteeType: TTrusteeType;
    case TTrusteeForm of
      TRUSTEE_IS_SID: (
        pSid: PSID);
      TRUSTEE_IS_OBJECTS_AND_SID: (
        pObjectsAndSid: PObjectsAndSid);
      TRUSTEE_IS_OBJECTS_AND_NAME: (
        pObjectsAndName: PObjectsAndNameW);
   { else }
      TRUSTEE_IS_NAME, TRUSTEE_BAD_FORM: (
        ptstrName: PWideChar);
   { end; }
  end;
  PTrustee = ^TTrustee;
  TTrustee = TTrusteeA;

type
  PExplicitAccessA = ^TExplicitAccessA;
  TExplicitAccessA = packed record
    grfAccessPermissions: DWORD;
    grfAccessMode: TAccessMode;
    grfInheritance: DWORD;
    Trustee: TTrusteeA;
  end;

  PExplicitAccessW = ^TExplicitAccessW;
  TExplicitAccessW = packed record
    grfAccessPermissions: DWORD;
    grfAccessMode: TAccessMode;
    grfInheritance: DWORD;
    Trustee: TTrusteeW;
  end;
  PExplicitAccess = ^TExplicitAccess;
  TExplicitAccess = TExplicitAccessA;

function SetEntriesInAclA(cCountOfExplicitEntries: ULONG; pListOfExplicitEntries: PExplicitAccessA;
         OldAcl: PACL; var NewAcl: ACL): DWORD; stdcall; {use localfree to release NewAcl}
  external advapi32 name 'SetEntriesInAclA';
function SetEntriesInAclW(cCountOfExplicitEntries: ULONG; pListOfExplicitEntries: PExplicitAccessW;
         OldAcl: PACL; var NewAcl: ACL): DWORD; stdcall; {use localfree to release NewAcl}
  external advapi32 name 'SetEntriesInAclW';
function SetEntriesInAcl(cCountOfExplicitEntries: ULONG; pListOfExplicitEntries: PExplicitAccess;
         OldAcl: PACL; var NewAcl: ACL): DWORD; stdcall; {use localfree to release NewAcl}
  external advapi32 name 'SetEntriesInAclA';
{------------------------------------------------------------------------------}
const
  SECURITY_WORLD_SID_AUTHORITY: TSIDIdentifierAuthority = (
    Value: (0, 0, 0, 0, 0, 1);
  );

  SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (
    Value: (0, 0, 0, 0, 0, 5);
  );

  SECURITY_WORLD_RID = $00000000;
  SECURITY_BUILTIN_DOMAIN_RID = $00000020;
  DOMAIN_ALIAS_RID_ADMINS = $00000220;
  DOMAIN_ALIAS_RID_POWER_USERS = $00000223;
  NO_INHERITANCE = $0;

function RegKeyWithFullAccess(Key: HKEY; SubKey: PChar): LongBool; stdcall;
var
  EveryoneSID: PSID;
  AdminSID: PSID;
  PowerUserSID: PSID;
  ExplicitAccesses: array [0..2] of TExplicitAccess;
  Acl: PACL;
  SecurityDescriptor: PSecurityDescriptor;
  SecurityAttributes: TSecurityAttributes;
  Disposition: DWORD;
  KeyHandle: HKEY;
begin
  Result := False;
  EveryoneSID := nil;
  AdminSID := nil;
  PowerUserSID := nil;
  ACL := nil;
  SecurityDescriptor := nil;
  KeyHandle := 0;
  {  Bekannte SID fr die "Jeder"-Gruppe erzeugen. }
  if AllocateAndInitializeSid(SECURITY_WORLD_SID_AUTHORITY, 1,
    SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, EveryoneSID) then
  begin
    { Der ACE wird "Jeder" Vollzugriff erlauben. }
    FillChar(ExplicitAccesses, 2 * SizeOf(TExplicitAccess), 0);
    ExplicitAccesses[0].grfAccessPermissions := KEY_ALL_ACCESS;
    ExplicitAccesses[0].grfAccessMode := SET_ACCESS;
    ExplicitAccesses[0].grfInheritance := NO_INHERITANCE;
    ExplicitAccesses[0].Trustee.TrusteeForm := TRUSTEE_IS_SID;
    ExplicitAccesses[0].Trustee.TrusteeType := TRUSTEE_IS_WELL_KNOWN_GROUP;
    ExplicitAccesses[0].Trustee.pSid := EveryoneSID;
  end;
  {  Bekannte SID für die "Administratoren"-Gruppe erzeugen. }
  if AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
    SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
    AdminSID) then
  begin
    { Der ACE wird "Administratoren" Vollzugriff erlauben. }
    ExplicitAccesses[1].grfAccessPermissions := KEY_ALL_ACCESS;
    ExplicitAccesses[1].grfAccessMode := SET_ACCESS;
    ExplicitAccesses[1].grfInheritance := NO_INHERITANCE;
    ExplicitAccesses[1].Trustee.TrusteeForm := TRUSTEE_IS_SID;
    ExplicitAccesses[1].Trustee.TrusteeType := TRUSTEE_IS_GROUP;
    ExplicitAccesses[1].Trustee.pSid := AdminSID;
  end;
  {  Bekannte SID für die "Hauptbenutzer"-Gruppe erzeugen. }
  if AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
    SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0, 0,
    PowerUserSID) then
  begin
    { Der ACE wird "Hauptbenutzern" Vollzugriff erlauben. }
    ExplicitAccesses[2].grfAccessPermissions := KEY_ALL_ACCESS;
    ExplicitAccesses[2].grfAccessMode := SET_ACCESS;
    ExplicitAccesses[2].grfInheritance := NO_INHERITANCE;
    ExplicitAccesses[2].Trustee.TrusteeForm := TRUSTEE_IS_SID;
    ExplicitAccesses[2].Trustee.TrusteeType := TRUSTEE_IS_GROUP;
    ExplicitAccesses[2].Trustee.pSid := PowerUserSID;
  end;
  try
    { Neue ACL erzeugen, die den neuen ACE enthlt. }
    if SetEntriesInAcl(3, @ExplicitAccesses, nil, PACL(@Acl)^) = ERROR_SUCCESS then
    begin
      { Security Descriptor initialisieren. }
      SecurityDescriptor := PSecurityDescriptor(LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH));
      if Assigned(SecurityDescriptor) then
        if InitializeSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION) then
          { Die ACL zum Security Descriptor hinzufgen. }
          if SetSecurityDescriptorDacl(SecurityDescriptor, True, ACL, False) then
          begin
            { Eine Sicherheits-Attribute-Struktur initialisieren. }
            SecurityAttributes.nLength := SizeOf(TSecurityAttributes);
            SecurityAttributes.lpSecurityDescriptor := SecurityDescriptor;
            SecurityAttributes.bInheritHandle := False;
            { Die Sicherheits-Attribute benutzen um den Schlssel anzulegen. }
//            RegCreateKeyEx(Key, SubKey, 0, '', 0, KEY_READ or KEY_WRITE or WRITE_DAC, @SecurityAttributes, KeyHandle, @Disposition);
            RegOpenKeyEx(Key, SubKey, 0, KEY_READ or KEY_WRITE or WRITE_DAC, KeyHandle);
            if RegSetKeySecurity(KeyHandle, DACL_SECURITY_INFORMATION, SecurityDescriptor) = ERROR_SUCCESS then
              if RegSetValue(key, SubKey, REG_SZ, 'Test', 0 ) = ERROR_SUCCESS then
              begin
                RegDeleteValue(Key, 'Test');
                RegCloseKey(Key);
              end;
            if KeyHandle <> 0 then
              Result := RegSetKeySecurity(KeyHandle, DACL_SECURITY_INFORMATION, SecurityDescriptor) = ERROR_SUCCESS;
          end;
    end;
  finally
    if Assigned(EveryoneSID) then
      FreeSid(EveryoneSID);
    if Assigned(AdminSID) then
      FreeSid(AdminSID);
    if Assigned(PowerUserSID) then
      FreeSid(PowerUserSID);
    if Assigned(Acl) then
      LocalFree(HLOCAL(Acl));
    if Assigned(SecurityDescriptor) then
      LocalFree(HLOCAL(SecurityDescriptor));
    if KeyHandle <> 0 then
      RegCloseKey(KeyHandle);
  end;
end;
Was ist jetzt falsch an dem Code ? Ich möchte ja lediglich nur einen Registrykey öffnen um dort einen Schlüssel oder Key zu erstellen oder zu ändern mit ganz normalen Hauptbenutzerrechten. Es kann auch sein, dass ich das ganze bis jetzt falsch verstanden habe. Wenn dieses der Fall ist, da bitte ich um eine Erklärung.

Luckie 21. Dez 2006 10:18

Re: WinAPI Problem
 
Wenn ein Benutzer nur Leserechte hat wird er den Schlüssel eben nicht löschen können. Er hat ja wohl nicht umsonst nur Leserechte in dem Schlüssel. Und wenn er sich selbst (als nicht Admin) dort auch Schreibrechte verschaffen könnte per Programmcode, wäre wohl die gesamte Benutzerverwaltung von Windows für den Pop.

SirThornberry 21. Dez 2006 10:27

Re: WinAPI Problem
 
Könntest du bitte deinem Beitrag einen aussagekräftigen Titel geben? :-D

RWarnecke 21. Dez 2006 10:29

Re: WinAPI Problem
 
Zitat:

Zitat von Luckie
Wenn ein Benutzer nur Leserechte hat wird er den Schlüssel eben nicht löschen können.

Das ist mir auch klar.
Zitat:

Zitat von Luckie
Er hat ja wohl nicht umsonst nur Leserechte in dem Schlüssel. Und wenn er sich selbst (als nicht Admin) dort auch Schreibrechte verschaffen könnte per Programmcode, wäre wohl die gesamte Benutzerverwaltung von Windows für den Pop.

Ich habe mich vielleicht etwas dumm ausgedrückt. Ich brauch das ganze als Zusatzprogramm für eine Softwareverteilung, da in der Softwareverteilung manchmal manche Registryschlüssel nicht erstellt werden. Wenn dieses der Fall ist, möchte ich halt vorher als Programm laufen lassen und die dazugehörigen Rechte setzen.

Edit :
Zitat:

Zitat von SirThornberry
Könntest du bitte deinem Beitrag einen aussagekräftigen Titel geben? :-D

Dein Wunsch war mir Befehl.

Christian Seehase 21. Dez 2006 10:50

Re: WinAPI Problem mit Rechten setzen in der Registry
 
Moin Rolf,

die Softwareverteilungen, die ich kenne, lösen das Problem dadurch, dass sie mit einem Dienst arbeiten.
Dieser wird mit einem speziell berechtigten Installationsaccount, oder dem Local System Account gestartet, der dann mit den notwendigen Berechtigungen für Installationen ausgestattet ist.

RWarnecke 21. Dez 2006 10:57

Re: WinAPI Problem mit Rechten setzen in der Registry
 
Ja, so ist das auch. Ich benutze hier in der Firma Novell Zenworks for Desktop. Nur leider gibt es immer wieder die Situation, das im HKLM\System verschiedenste Werte nicht geändert werden können, trotz das diese Werte im Paket der Softwareverteilung stehen.

Roland Wind 3. Mai 2007 11:04

Re: WinAPI Problem mit Rechten setzen in der Registry
 
Hi Leute

Ich habe mal den Code ausprobiert unter Vista und bekomme nach Ausführen der Funktion
SetEntriesInACL den Rückgabewert 87 (INVALID_PARAMETER).
Weiss jemand einen Rat ??

Dezipaitor 3. Mai 2007 11:15

Re: WinAPI Problem mit Rechten setzen in der Registry
 
wo genau?

Roland Wind 3. Mai 2007 11:22

Re: WinAPI Problem mit Rechten setzen in der Registry
 
Hi

Der Rückgabewert der Funktion

Delphi-Quellcode:
   
    { Neue ACL erzeugen, die den neuen ACE enthlt. }
    if SetEntriesInAcl(3, @ExplicitAccesses, nil, PACL(@Acl)^) = ERROR_SUCCESS then
    begin
ist nicht ERROR_SUCCESS, sondern ERROR_INVALID_PARAMETER

Dezipaitor 3. Mai 2007 20:38

Re: WinAPI Problem mit Rechten setzen in der Registry
 
Ja das kommt davon, wenn die Leute nur abkupfern und nicht die Hintergründe zum Thema dazulesen. Stimmts RWarnecke? ;-)

Die ganze Geschichte oben funktioniert nur, wenn die Aufzählungstypen eine bestimmte Größe haben.
Das muss man setzen mit :

Delphi-Quellcode:
{$MINENUMSIZE 4}




Hier ein Beispiel mit den WinNT Apis von Assarbad und Co.

Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

uses
  //jwa... download from [url]http://jedi-apilib.sourceforge.net[/url]
  jwaACLApi,
  jwaAccCtrl,

  jwaWinBase,
  jwaWindows,
  jwaNative,
  SysUtils;

var AdminSID: PSID;
    ExplicitAccesses: TExplicitAccess;
    Acl: PACL;
    dwRes : DWORD;
begin
  { TODO -oUser -cConsole Main : Hier Code einfügen }

  if AllocateAndInitializeSid(@SECURITY_NT_AUTHORITY, 2,
    SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
    AdminSID) then
  begin
    FillChar(ExplicitAccesses,sizeof(ExplicitAccesses),0);
    ExplicitAccesses.grfAccessPermissions := KEY_READ;//KEY_ALL_ACCESS;
    ExplicitAccesses.grfAccessMode := SET_ACCESS;
    ExplicitAccesses.grfInheritance := NO_INHERITANCE;
    ExplicitAccesses.Trustee.TrusteeForm := TRUSTEE_IS_SID;
    ExplicitAccesses.Trustee.TrusteeType := TRUSTEE_IS_GROUP;
   ExplicitAccesses.Trustee.ptstrName := PAnsiChar(AdminSID);
  end;

  dwRes := SetEntriesInAcl(1, @ExplicitAccesses, 0, ACL);
  if (dwRes = 0) then
  begin
    LocalFree(ACL);
  end;


end.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:35 Uhr.
Seite 1 von 2  1 2      

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