Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
3-1202464120
ANB
2008-02-08 12:48
2008.07.27
Векторные запросы. Оракл и все остальные СУБД


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


2-1214041286
zep
2008-06-21 13:41
2008.07.27
Hint в тексте


6-1190821557
Rav
2007-09-26 19:45
2008.07.27
Как заставить IndySMTP отправлять Subject кириллицей?


2-1214410609
Анониммм
2008-06-25 20:16
2008.07.27
В каком событии отслеживать перемещение формы?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский