Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.07.27;
Скачать: CL | DM;

Вниз

Файловая безопасность в 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 вся ветка

Текущий архив: 2008.07.27;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.018 c
15-1212840446
Vlad Oshin
2008-06-07 16:07
2008.07.27
как работает и почему такой ответ


15-1213095081
Res
2008-06-10 14:51
2008.07.27
текст с картинки


15-1213461414
Kostafey
2008-06-14 20:36
2008.07.27
С днем рождения ! 14 июня


3-1202913301
AlexeyMir
2008-02-13 17:35
2008.07.27
Кеширование БД


15-1212761210
Ega23
2008-06-06 18:06
2008.07.27
Не дать организьму умереть от обезвоживания?