Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
Delphi 7 Professional
|
CreateFile und Security Attributes
27. Jun 2007, 22:54
hi
das folgende Problem habe ich schon vor längerer Zeit festgestellt. Jedoch bis jetzt nichts dazu finden können. Vielleicht kennt ein einsamer Wanderer, der hier zufällig vorbeikommt die Lösung oder weitere Materialien.
Das Problem habe ich bei CreateFile mit dem Parameter SecurityAttributes. Wenn ich eine eigene DACL dort hineinlege, dann wird diese ignoriert und stattdessen, werden die Sicherheitseinstellungen vom Elternordner übernommen.
Hier gebe ich mal den Quelltext meines Unit-Testings an, die meine SecurityLibrary testen soll.
Es sollte in der Datei SecurityXXXX.pas kompilierbar sein
Delphi-Quellcode:
function TSecureFileObjectTests.GetSecurityFileNameTemp(
out HasSACL: Boolean): String;
var
pTempName : Array[0..MAX_PATH+1] of char;
bI : Boolean;
pSecAttr : jwaWinBase.PSecurityAttributes;
handle : THANDLE;
SDesc : TSecurityDescriptor;
pDACL : jwaWinNT.PACL;
b : Boolean;
c : Cardinal;
begin
CheckNotEquals(0,
GetTempFileName(' .', // LPCTSTR lpPathName,
' SMLTest', // LPCTSTR lpPrefixString,
0, // UINT uUnique,
@pTempName // LPTSTR lpTempFileName
));
//File does not exist!!
SDesc := TSecurityDescriptor.Create;
SDesc.Owner := SecurityThreadUserSID; //current process user
SDesc.OwnOwner := false;
// SDesc.DACL.Add(TDiscretionaryAccessControlEntryAllow.Create(nil,[],FILE_ALL_ACCESS,SecurityThreadUserSID, false));
// SDesc.DACL.Add(TDiscretionaryAccessControlEntryAllow.Create(nil,[],FILE_ALL_ACCESS,LocalSystemSID, false));
// SDesc.DACL.Add(TDiscretionaryAccessControlEntryAllow.Create(nil,[af_NO_PROPAGATE_INHERIT_ACE],FILE_ALL_ACCESS,WorldSID, false));
SDesc.DACL.Add(TDiscretionaryAccessControlEntryAllow.Create( nil,[],FILE_ALL_ACCESS,GuestsSID, false));
if IsPrivilegeSet(SE_SECURITY_NAME) then
begin
EnablePrivilege(SE_SECURITY_NAME, pst_Enable);
SDesc.SACL.Add(TAuditAccessControlEntry.Create( nil,true, false, FILE_ALL_ACCESS,SDesc.Owner,false));
SDesc.SACL.Add(TAuditAccessControlEntry.Create( nil,true, false, FILE_ALL_ACCESS,WorldSID,false));
HasSACL := true;
end
else
HasSACL := false;
result := ' ';
try
//create SA strcture with no inheritance (false))
pSecAttr := SDesc.Create_SA(false);
handle := jwaWindows.CreateFile(pTempName,
FILE_ALL_ACCESS,
0,
Pointer(pSecAttr),
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0);
CheckNotEquals(Integer(INVALID_HANDLE_VALUE),Integer( handle), ESMSecurityException.GetLastErrorMessage());
CloseHandle( handle);
//XXXXXXXXXXXXXXx
//another way to set security without using TSecureFileObject
//remove old dac
TSecureGeneralObject.SetNamedSecurityInfo(pTempName,
SE_FILE_OBJECT,
[sif_OWNER_SECURITY_INFORMATION],
SDesc.Owner,
nil,
nil,
nil);
TSecureGeneralObject.SetNamedSecurityInfo(pTempName,
SE_FILE_OBJECT,
[sif_DACL_SECURITY_INFORMATION],
SDesc.Owner,
nil,
SDesc.DACL,
nil);
finally
SDesc.Free_SA(pSecAttr);
if IsPrivilegeSet(SE_SECURITY_NAME) then
begin
EnablePrivilege(SE_SECURITY_NAME, pst_Disable);
end;
end;
result := pTempName;
end;
Wie man hier sehen kann, wird eine neuer SecurityDescriptor gesetzt.
Delphi-Quellcode:
handle := jwaWindows.CreateFile(pTempName,
FILE_ALL_ACCESS,
0,
Pointer(pSecAttr),
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0);
Nur wird der SD ignoriert.
Was jedoch funktioniert ist folgendes:
Delphi-Quellcode:
TSecureGeneralObject.SetNamedSecurityInfo(pTempName,
SE_FILE_OBJECT,
[sif_OWNER_SECURITY_INFORMATION],
SDesc.Owner,
nil,
nil,
nil);
TSecureGeneralObject.SetNamedSecurityInfo(pTempName,
SE_FILE_OBJECT,
[sif_DACL_SECURITY_INFORMATION],
SDesc.Owner,
nil,
SDesc.DACL,
nil);
Man muss den SD zweimal setzen. Das erste Mal löscht man ihn,
und das zweite mal setzt man ihn.
Dies hab ich jedoch nur aus Tests erfahren. Dokumentiert hab ich es nicht gefunden.
|