Форум: "WinAPI";
Текущий архив: 2008.07.27;
Скачать: [xml.tar.bz2];
ВнизФайловая безопасность в NTFS Найти похожие ветки
← →
roughneck (2007-10-23 15:25) [0]Как получить и изменить безопасность файлов?
Я делаю следующее но работает очень долго:
1. GetFileSecurity
2. GetSecurityDescriptorDACL
3. GetACECount
4. цикл по всем acount-ам
а. LookupAccountSid
б. GetUserFullName
в. GetFileGenericSecurity
5. полученный список обрабатываю (это быстро)
6. применяю обработанный список (это почти также как получать только Set-функции)
Может есть какой-то другой способ попроше, главно чтоб побыстрее.
Спасибо.
← →
Ins © (2007-10-23 15:39) [1]
> Как получить и изменить безопасность файлов?
1. GetNamedSecurityInfo - сразу же получаем DACL, имея только имя файла, 2. SetEntriesInAcl - устанавливаем новые элементы в DACL,
3. SetNamedSecurityInfo - новый DACL
Ваш п.4. я вообще не понял. Что нужно то?
← →
roughneck (2007-10-24 07:50) [2]п.4. и получается еще п.3. нужны чтоб из DACL получить ACE (GetACE) а из него PSID, а по SID-у получаем имя пользователя. Также из ACE получаем маску галочек доступа.
← →
Ins © (2007-10-24 09:44) [3]
> а по SID-у получаем имя пользователя.
Зачем? Что вам нужно, объясните подробнее плз...
← →
roughneck (2007-10-24 13:12) [4]Нужно получить список пользователей и их права (14 галочек). Затем изменить этот список и применить. Прям как в винде.
Проведя некий анализ выявил что долго выполняются функции: LookupAccountSid и LookupAccountName. Причем если работать по сети (сервер, домен и все такое), то долго, а на локальной машине побыстрее выполняется.
← →
Ins © (2007-10-24 13:20) [5]
> Нужно получить список пользователей
Тех пользователей и групп, которые присутствуют в ACL? Тогда да, пройдитесь в цикле по всем элементам списка, запомнить где-либо уникальные SID и получить по ним имя аккаунта.
> и их права (14 галочек)
GetEffectiveRightsFromAcl - как раз то, что вам нужно.
> Затем изменить этот список и применить.
Об этом уже сказал.
> Проведя некий анализ выявил что долго выполняются функции:
> LookupAccountSid и LookupAccountName. Причем если работать
> по сети (сервер, домен и все такое), то долго, а на локальной
> машине побыстрее выполняется.
Ничего удивительного.
← →
roughneck (2007-10-24 13:40) [6]
> > Проведя некий анализ выявил что долго выполняются функции:
>
> > LookupAccountSid и LookupAccountName. Причем если работать
>
> > по сети (сервер, домен и все такое), то долго, а на локальной
>
> > машине побыстрее выполняется.
>
> Ничего удивительного.
а по быстрее нет функций?
← →
Ins © (2007-10-24 13:42) [7]
> и их права (14 галочек)
А вообще-то, по хорошему, тут уточнить нужно бы. Дело в том, что есть два алгоритма определения прав учетной записи. По первому работает функция GetEffectiveRightsFromAcl. По второму - AccessCheck. Для формирования "списка галочек как в винде" используется первая, а для проверки прав доступа при открытии объекта - вторая. Галочка еще не гарантирует разрешение доступа, так как он может быть запрещен для группы, в которую входит аккаунт. Проще говоря, GetEffectiveRightsFromAcl возвращает маску прав, разрешенных в DACL, именно для данного SID, не учитывая группы, в которые аккаунт может входить. Т.е. она работает только с ACL. AccessCheck же еще извлекает из маркера доступа SID-ы групп и учитывает их. Т.е. она работает не только с ACL, но и с Access Token вызывающего потока.
← →
Ins © (2007-10-24 14:24) [8]
> а по быстрее нет функций?
Я думаю, дело не в плохой функции, а в том, что для выполнения этой операции требуется обатиться к удаленному компьютеру.
← →
roughneck (2007-10-24 14:29) [9]
> уточнить нужно бы
Пока мне нужно получать "галочки как в винде" и изменять их. Вообще смысл проги в том, чтобы устанавливать права по расписанию. Например, дать доступ юзеру на чтение-запись на такую-то папку/файл с такого-то по такое-то время. Весь "интерфейс безопасности" примерно как в винде.
← →
BiN © (2007-10-24 17:29) [10]
> roughneck (24.10.07 14:29) [9]
>
>
> > уточнить нужно бы
>
> Пока мне нужно получать "галочки как в винде" и изменять
> их. Вообще смысл проги в том, чтобы устанавливать права
> по расписанию. Например, дать доступ юзеру на чтение-запись
> на такую-то папку/файл с такого-то по такое-то время. Весь
> "интерфейс безопасности" примерно как в винде.
пример использования стандартного диалога редактирования настроек безопасности (ISecurityInformation) есть у Рихтера-Кларка.. прямая ссылка на примеры с исходниками (с++):
http://irazin.ru/downloads/booksamples/Richter_Clark.zip
← →
Eraser © (2007-10-24 17:47) [11]
> roughneck (24.10.07 14:29) [9]
дать пример работы с ISecurityInformation на delphi?
← →
vpbar © (2007-10-24 20:37) [12]>>BiN © (24.10.07 17:29) [10]
О! Спасибо. Мне как раз нужно права в XP Home настроить. Уже почти собрался File Security Manager покупать, а тут такое да еще в исходниках. Супер!!
← →
roughneck (2007-10-25 05:59) [13]
> дать пример работы с ISecurityInformation на delphi?
Очень хорошо бы
← →
Eraser © (2007-10-27 01:13) [14]> [13] roughneck (25.10.07 05:59)
примерно такunit SecurityPage;
interface
uses
Classes, SysUtils, Dialogs, JwaWinNT, JwaAclApi, JwaAccCtrl, JwaWinBase,
JwaAclUI, JwaWinType, JwaWinError;
type
TAccessControl = class
private
FAccessData: TStream;
function GetACL: PACL;
function GetOwnerSID: PSID;
function StoreACL(ApACL: PACL): Boolean;
procedure FreeSD(pSD: PSECURITY_DESCRIPTOR);
public
constructor Create(AccessInfo: TStream); reintroduce; overload;
function GetSD: PSECURITY_DESCRIPTOR;
function SetSD(pSD: PSECURITY_DESCRIPTOR): Boolean;
end;
TSecurityInfo = class(TInterfacedObject, ISecurityInformation)
private
FAccessControl: TAccessControl;
protected
function GetObjectInformation(out pObjectInfo: SI_OBJECT_INFO): HRESULT; stdcall;
function GetSecurity(RequestedInformation: SECURITY_INFORMATION;
out ppSecurityDescriptor: PSECURITY_DESCRIPTOR; fDefault: BOOL): HRESULT; stdcall;
function SetSecurity(SecurityInformation: SECURITY_INFORMATION;
pSecurityDescriptor: PSECURITY_DESCRIPTOR): HRESULT; stdcall;
function GetAccessRights(pguidObjectType: LPGUID; dwFlags: DWORD;
out ppAccess: PSI_ACCESS; out pcAccesses, piDefaultAccess: ULONG): HRESULT; stdcall;
function MapGeneric(pguidObjectType: LPGUID; pAceFlags: PUCHAR;
pMask: PACCESS_MASK): HRESULT; stdcall;
function GetInheritTypes(out ppInheritTypes: PSI_INHERIT_TYPE;
out pcInheritTypes: ULONG): HRESULT; stdcall;
function PropertySheetPageCallback(hwnd: HWND; uMsg: UINT;
uPage: SI_PAGE_TYPE): HRESULT; stdcall;
public
constructor Create(AccessInfo: TStream); reintroduce; overload;
destructor Destroy; override;
end;
const
GUID_NULL: TGUID = "{00000000-0000-0000-0000-000000000000}";
AccessMap: array[0..1] of SI_ACCESS = (
(
pguid: @GUID_NULL;
mask: $01;
pszName: "Full Control";
dwFlags: SI_ACCESS_GENERAL
),
( // We do not use it in this version!
pguid: @GUID_NULL;
mask: $02;
pszName: "View only";
dwFlags: SI_ACCESS_GENERAL
)
);
var
AccessMasks: GENERIC_MAPPING = (
GenericRead: STANDARD_RIGHTS_READ;
GenericWrite: STANDARD_RIGHTS_WRITE;
GenericExecute: STANDARD_RIGHTS_EXECUTE;
GenericAll: {STANDARD_RIGHTS_REQUIRED or }
STANDARD_RIGHTS_READ or
STANDARD_RIGHTS_WRITE or
STANDARD_RIGHTS_EXECUTE;
);
implementation
{ TSecurityInfo }
constructor TSecurityInfo.Create(AccessInfo: TStream);
begin
inherited Create;
FAccessControl := TAccessControl.Create(AccessInfo);
end;
destructor TSecurityInfo.Destroy;
begin
FAccessControl.Free;
inherited Destroy;
end;
function TSecurityInfo.GetAccessRights(pguidObjectType: LPGUID; dwFlags: DWORD;
out ppAccess: PSI_ACCESS; out pcAccesses, piDefaultAccess: ULONG): HRESULT;
begin
ppAccess := @AccessMap[0];
pcAccesses := 1;
piDefaultAccess := 0;
Result := S_OK;
end;
function TSecurityInfo.GetInheritTypes(out ppInheritTypes: PSI_INHERIT_TYPE;
out pcInheritTypes: ULONG): HRESULT;
begin
ppInheritTypes := nil;
pcInheritTypes := 0;
Result := S_OK;
end;
function TSecurityInfo.GetObjectInformation(
out pObjectInfo: SI_OBJECT_INFO): HRESULT;
begin
pObjectInfo.dwFlags := SI_EDIT_PERMS or SI_NO_ACL_PROTECT
or SI_PAGE_TITLE;
pObjectInfo.hInstance := SysInit.HInstance;
pObjectInfo.pszServerName := nil;
pObjectInfo.pszObjectName := "My object name";
Result := S_OK;
end;
function TSecurityInfo.GetSecurity(RequestedInformation: SECURITY_INFORMATION;
out ppSecurityDescriptor: PSECURITY_DESCRIPTOR; fDefault: BOOL): HRESULT;
begin
ppSecurityDescriptor := FAccessControl.GetSD;
if ppSecurityDescriptor <> nil then
Result := S_OK
else
Result := E_FAIL;
end;
function TSecurityInfo.MapGeneric(pguidObjectType: LPGUID; pAceFlags: PUCHAR;
pMask: PACCESS_MASK): HRESULT;
begin
MapGenericMask(pMask^, AccessMasks);
Result := S_OK;
end;
function TSecurityInfo.PropertySheetPageCallback(hwnd: HWND; uMsg: UINT;
uPage: SI_PAGE_TYPE): HRESULT;
begin
Result := S_OK;
end;
function TSecurityInfo.SetSecurity(SecurityInformation: SECURITY_INFORMATION;
pSecurityDescriptor: PSECURITY_DESCRIPTOR): HRESULT;
begin
if FAccessControl.SetSD(pSecurityDescriptor) then
Result := S_OK
else
Result := E_FAIL;
end;
{ TAccessControl }
constructor TAccessControl.Create(AccessInfo: TStream);
begin
inherited Create;
FAccessData := AccessInfo;
end;
procedure TAccessControl.FreeSD(pSD: PSECURITY_DESCRIPTOR);
var
pOwnerSID, pGroupSID: PSID;
pDACL, pSACL: PACL;
bOwnerDefaulted, bGroupDefaulted, bDaclPresent, bSaclDefaulted: Bool;
bDaclDefaulted, bSaclPresent: LongBool;
begin
if pSD <> nil then
begin
pOwnerSID := nil;
pGroupSID := nil;
if GetSecurityDescriptorOwner(pSD, pOwnerSID, @bOwnerDefaulted) then
begin
try
HeapFree(GetProcessHeap, 0, pOwnerSID);
except
end;
end;
if GetSecurityDescriptorGroup(pSD, pGroupSID, @bGroupDefaulted) then
begin
try
HeapFree(GetProcessHeap, 0, pGroupSID);
except
end;
end;
GetSecurityDescriptorDacl(pSD, bDaclPresent, pDACL, bDaclDefaulted);
GetSecurityDescriptorSacl(pSD, bSaclPresent, pSACL, bSaclDefaulted);
end;
try
if pSD <> nil then
FreeMem(pSD);
if bDaclPresent and (pDACL <> nil) then
FreeMem(pDACL);
if bSaclPresent and (pSACL <> nil) then
FreeMem(pSACL);
except
end;
end;
function TAccessControl.GetACL: PACL;
begin
Result := nil;
try
if FAccessData.Size < SizeOf(ACL) then
exit;
FAccessData.Position := 0;
GetMem(Result, FAccessData.size);
FAccessData.Read(Result^, FAccessData.size);
except
end;
end;
function TAccessControl.GetOwnerSID: PSID;
var
pAdminSid: PSid;
SIDAuth: SID_IDENTIFIER_AUTHORITY;
begin
pAdminSid := nil;
SIDAuth := SECURITY_NT_AUTHORITY;
AllocateAndInitializeSid(@SIDAuth,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
pAdminSid);
Result := pAdminSid;
end;
← →
Eraser © (2007-10-27 01:14) [15]
function TAccessControl.GetSD: PSECURITY_DESCRIPTOR;
var
pntAcl: PACL;
pSD, pSelfRelativeSD: PSECURITY_DESCRIPTOR;
BufferLength: Cardinal;
begin
Result := nil;
BufferLength := 0;
try
pntAcl := GetACL;
if (pntAcl = nil) or (not IsValidAcl(pntAcl)) then
begin
GetMem(pntAcl, SizeOf(ACL));
if not InitializeAcl(pntAcl, SizeOf(ACL), ACL_REVISION) then
Exit;
end;
GetMem(pSD, SECURITY_DESCRIPTOR_MIN_LENGTH);
if not InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION) then
exit;
if not SetSecurityDescriptorDacl(pSD, true, pntAcl, false) then
exit;
if not SetSecurityDescriptorOwner(pSD, GetOwnerSID, false) then
exit;
if not SetSecurityDescriptorGroup(pSD, GetOwnerSID, false) then
exit;
MakeSelfRelativeSD(pSD, nil, BufferLength);
pSelfRelativeSD := PSECURITY_DESCRIPTOR(
LocalAlloc(0, BufferLength));
if not MakeSelfRelativeSD(pSD, pSelfRelativeSD, BufferLength) then
Exit;
FreeSD(pSD);
Result := pSelfRelativeSD;
finally
end;
end;
function TAccessControl.SetSD(pSD: PSECURITY_DESCRIPTOR): Boolean;
var
bDaclPresent, bDaclDefaulted: BOOL;
pDACL: PACL;
begin
pDACL := nil;
Result := false;
GetSecurityDescriptorDacl(pSD, bDaclPresent, pDACL, bDaclDefaulted);
if bDaclPresent and (pDACL <> nil) and IsValidAcl(pDACL) and StoreACL(pDACL) then
Result := true;
end;
function TAccessControl.StoreACL(ApACL: PACL): Boolean;
var
AclInfo: ACL_SIZE_INFORMATION;
nAclInformationLength: Cardinal;
begin
Result := false;
FAccessData.Size := 0;
FAccessData.Position := 0;
if ApACL = nil then
Exit;
try
nAclInformationLength := SizeOf(ACL_SIZE_INFORMATION);
GetAclInformation(ApACL, @AclInfo, nAclInformationLength,
AclSizeInformation);
FAccessData.Write(ApACL^, AclInfo.AclBytesInUse);
FAccessData.Position := 0;
Result := true;
except
end;
end;
end.
← →
Eraser © (2007-10-27 01:16) [16]пример из реального проекта, поэтому без даработки может не заработать.
PS необходимы заголовочный файлы winAPI от jedi, см. ftp://ftp.delphi-jedi.org/api/win32api.zip
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2008.07.27;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.009 c