Entwickler-Ecke

Windows API - Neue Berechtigung zu vorhandener File-ACL hinzufügen


Christian213 - Do 31.07.14 11:02
Titel: Neue Berechtigung zu vorhandener File-ACL hinzufügen
Hallo,

ich versuche über die WinAPI bei einem Fileobjekt eine zusätzliche Zugriffsberechtigung auf ACL-Ebene hinzuzufügen.
Ich habe dazu diesen C++ Quelltext hier als Vorlage genommen und ihn entsprechend angepasst: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379283%28v=vs.85%29.aspx
Mein Problem nun ist, dass "SetEntriesInAcl" mich mit "falscher Parameter" anmeckert. Ich habe keine Idee, wo der Fehler liegt.
Hier ist mein Quelltext:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
program acltest;

uses Windows,
     JwaWindows,
     SysUtils;
function AddFileACL(Filename, TrusteeName: AnsiString; AccessMode: ACCESS_MODE; Inheritance: dWord): Boolean; stdcall;
var
  ExplicitAccess : EXPLICIT_ACCESS;
  ExistingDacl : ACL;
  NewAcl : ACL;
  pNewAcl : PACL;
  psd : PSECURITY_DESCRIPTOR;
  R : Dword;
begin
  Result := false;
  pNewAcl := @NewAcl;
  try
    R := GetNamedSecurityInfo(pAnsiChar(Filename), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nilnil, @ExistingDacl, nil, psd);
    if R = ERROR_SUCCESS then
    begin
      try

        BuildExplicitAccessWithName(@ExplicitAccess, PAnsiChar(TrusteeName), ACCESS_ALL, AccessMode, Inheritance);

        (*
        ExplicitAccess.grfAccessPermissions := ACCESS_ALL;
        ExplicitAccess.grfAccessMode := AccessMode;
        ExplicitAccess.grfInheritance := Inheritance;
        ExplicitAccess.Trustee.TrusteeForm := TRUSTEE_IS_NAME;
        ExplicitAccess.Trustee.ptstrName := PAnsiChar(TrusteeName);
        *)


        R := SetEntriesInAcl(1, @ExplicitAccess, @ExistingDacl, pNewAcl);
        if R = ERROR_SUCCESS then
        begin
          R := SetNamedSecurityInfo(pAnsiChar(Filename), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nilnil, pNewAcl, nil);
          if R = ERROR_SUCCESS then
          begin
            Result := true;
          end
          else
            writeln('Error calling SetNamedSecurityInfo: ' + SysErrorMessage(R));
        end
        else
          writeln('Error calling SetEntriesInAcl: ' + SysErrorMessage(R));
      finally
      end;
    end
    else
      writeln('Error calling GetNamedSecurityInfo: ' + SysErrorMessage(R));
  finally
  end;
end;

begin
  if AddFileACL('C:\Users\keckc\Desktop\test.txt''Everyone', GRANT_ACCESS, NO_INHERITANCE) = true then
  begin
    writeln('Yep, it works!');
  end
  else begin
    writeln('Nope, try again!');
  end;
  readln;
end.


Der auskommentierte Block wurde durch den Aufruf von BuildExplicitAccessWithName ersetzt, es hat allerdings leider keine Änderung gebracht.

Hat jemand eine Idee?

Danke und viele Grüße
Christian


Christian213 - Do 31.07.14 14:23

So, ich habe die Probleme nun selbst gelöst. Einerseits waren die gewählten Types nicht richtig, anderseits kann man auf einem deutschen Windows scheinbar nicht davon ausgehen, dass der "Everyone"-User korrekt zum "Jeder"-Account gemappt wird. Ich habe dies nun so gelöst, dass in diesem Fall über die SID gearbeitet wird. Diese ist für "Jeder/Everyone" immer "S-1-1-0" (wenigstens etwas, was definiert ist ;-) ).
Hier der lauffähige Beispielcode für alle anderen, die auf der Suche nach einer Lösung für diese Aufgabe sind:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
program acltest;

uses Windows,
     JwaWindows,
     SysUtils;
function AddFileACL(Filename, TrusteeName: AnsiString; Permission: DWord; AccessMode: ACCESS_MODE; Inheritance: dWord): Boolean; stdcall;
var
  ExplicitAccess : EXPLICIT_ACCESS;
  ExistingDacl : PACL;
  NewAcl : PACL;
  psd : PSECURITY_DESCRIPTOR;
  R : Dword;
  pEveryoneSID : PSID;
begin
  Result := false;
  try
    R := GetNamedSecurityInfo(pAnsiChar(Filename), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nilnil, @ExistingDacl, nil, psd);
    if R = ERROR_SUCCESS then
    begin
      try
        If TrusteeName = 'Jeder' then
        begin
          if ConvertStringSidToSid('S-1-1-0', pEveryoneSID) = true then
          begin
            ExplicitAccess.grfAccessPermissions := Permission;
            ExplicitAccess.grfAccessMode := AccessMode;
            ExplicitAccess.grfInheritance := Inheritance;
            ExplicitAccess.Trustee.TrusteeForm := TRUSTEE_IS_SID;
            ExplicitAccess.Trustee.TrusteeType:= TRUSTEE_IS_WELL_KNOWN_GROUP;
            ExplicitAccess.Trustee.ptstrName := pAnsiChar(pEveryoneSID);
          end
          else begin
            writeln('Error calling ConvertStringSidToSid: ' + SysErrorMessage(R));
          end;
        end
        else begin
          BuildExplicitAccessWithName(@ExplicitAccess, PAnsiChar(TrusteeName), Permission, AccessMode, Inheritance);
        end;
        R := SetEntriesInAcl(1, @ExplicitAccess, ExistingDacl, NewAcl);
        if R = ERROR_SUCCESS then
        begin
          R := SetNamedSecurityInfo(pAnsiChar(Filename), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nilnil, NewAcl, nil);
          if R = ERROR_SUCCESS then
          begin
            Result := true;
          end
          else
            writeln('Error calling SetNamedSecurityInfo: ' + SysErrorMessage(R));
        end
        else
          writeln('Error calling SetEntriesInAcl: ' + SysErrorMessage(R));
      finally
      end;
    end
    else
      writeln('Error calling GetNamedSecurityInfo: ' + SysErrorMessage(R));
  finally
  end;
end;

begin
  if AddFileACL('C:\Users\keckc\Desktop\test.txt''Jeder', GENERIC_READ or GENERIC_EXECUTE, SET_ACCESS, NO_INHERITANCE) = true then
  begin
    writeln('Yep, it works!');
  end
  else begin
    writeln('Nope, try again!');
  end;
  readln;
end.

Viele Grüße
Christian