Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Права доступа в Win NT/2K/XP


Автор: Cheba 18.2.2004, 01:25
Как можно задать права доступа к файлу/папке для конкретного пользователя?
Если непонятно объяснил, то это можно делать в ХР/2К со вкладки Безопаснось в свойствах. И если я правильно понимяю механизм этих манипуляций, то это все делается только на NTFS. Короче, кто что знает - поделитесь.

Автор: p0s0l 18.2.2004, 07:32
Смотри функцию SetNamedSecurityInfo...

В принципе - вот пример:
Код
var
 SecurNTAuth  : SID_IDENTIFIER_AUTHORITY;
 psd : PSECURITY_DESCRIPTOR;
 du : PSID;
 pOldAcl, pNewAcl : PACL;
 ea : EXPLICIT_ACCESS;
 domlen, siz : cardinal;

const
 FileName : PChar = 'c:\test.txt';

begin
 SecurNTAuth := SECURITY_NT_AUTHORITY;

 if not AllocateAndInitializeSid (
   @SecurNTAuth,
   2,
   SECURITY_BUILTIN_DOMAIN_RID,
   DOMAIN_ALIAS_RID_POWER_USERS,
   0, 0, 0, 0, 0, 0,
   du) then
 begin
   WinError;
   Exit;
 end;

 if GetNamedSecurityInfo (
   FileName,
   SE_FILE_OBJECT,
   DACL_SECURITY_INFORMATION,
   nil,
   nil,
   @pOldACL,
   nil,
   psd) <> ERROR_SUCCESS then
 begin
   WinError;
   LocalFree (cardinal(psd));
   LocalFree (cardinal(du));
   Exit;
 end;

 ea.grfAccessMode := GRANT_ACCESS;
 ea.grfAccessPermissions := GENERIC_ALL;
//  ea.grfInheritance := INHERIT_ONLY;
 ea.grfInheritance := INHERIT_ONLY_ACE;
 ea.grfInheritance := NO_INHERITANCE;
 ea.Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
 ea.Trustee.pMultipleTrustee := nil;
 ea.Trustee.TrusteeForm := TRUSTEE_IS_SID;
 ea.Trustee.TrusteeType := TRUSTEE_IS_UNKNOWN;

 ea.Trustee.ptstrName := PChar(du);

 if (SetEntriesInAcl(
   1,
   @ea,
   pOldAcl,
   pNewAcl) <> ERROR_SUCCESS) then
 begin
   WinError;
   LocalFree (cardinal(psd));
   LocalFree (cardinal(du));
   LocalFree (cardinal(pOldAcl));
   Exit;
 end;

 if (SetNamedSecurityInfo(
    FileName,
    SE_FILE_OBJECT,
    DACL_SECURITY_INFORMATION,
    nil,
    nil,
    pNewAcl,
    nil) <> ERROR_SUCCESS) then
 begin
   WinError;
   LocalFree (cardinal(psd));
   LocalFree (cardinal(du));
   LocalFree (cardinal(pOldAcl));
   Exit;
 end;

 LocalFree (cardinal(psd));
 LocalFree (cardinal(du));
 LocalFree (cardinal(pOldAcl));
 LocalFree (cardinal(pNewAcl));
end;

Тут к файлу test.txt добавляется доступ Power User'ам. Для задания конкретного юзера можно использовать вначале LookupAccounSid вместо AllocateAndInitializeSid...

Автор: Cheba 19.2.2004, 00:21
Спасибо.
Вот только это работает если юзверя еще нет в списке прав доступа (или как там он зовется). Попробовал через LookupAccountSid. Работает только если юзвер уже в списке.
А как сделать так чтобы всегда работало?

Автор: p0s0l 19.2.2004, 20:20
Цитата
Вот только это работает если юзверя еще нет в списке прав доступа (или как там он зовется). Попробовал через LookupAccountSid. Работает только если юзвер уже в списке.
А как сделать так чтобы всегда работало?

Вообще-то что-то у тебя не то, т.к. что LookupAccountSid, что AllocateAndInitializeSid нужны для получения SID юзера, дальнейшие действия одинаковы. А если ты получаешь этими функциями один и тот же SID, то и результат работы должен быть один и тот же...

Автор: NiJazz 19.2.2004, 21:23
p0s0l, что-то код больно знакомый! Интересно видеть Паскаль-аналог. smile.gif

Прошу прощения за оффтоп, но почему у меня VC++ с функцией LookupAccountSid не работает, хотя я всё, что нужно подключаю. Говорит, что не знает такое. Как это исправить?

Автор: Medved 20.2.2004, 13:28
Цитата(NiJazz @ 20.2.2004, 00:23)
Прошу прощения за оффтоп, но почему у меня VC++ с функцией LookupAccountSid не работает, хотя я всё, что нужно подключаю. Говорит, что не знает такое. Как это исправить?

Нет. Вы нарушаете сразу два правила форума.
1.Новое сообщение должно иметь прямое отношение к разделу форума. Сообщения которые запущены в несоответствующий раздел будут удалены или перемещены администрацией.
2. Запрещаются дискуссии не имеющие отношения к теме сообщения. Такие ответы будут квалифицированы как "офтопик" и удалены администрацией форума.

Автор: Cheba 21.2.2004, 11:20
Все дело было в том, что мнен нужно было дать права доступа юзверю не встроеному, а просто зарегистрированному в системе. Мне было известно его имя. И пробовал я получить его SID через LookupAccountName. В общем, с ним-то и были проблемы. Но решение нашлось. Может, кому нужно станет... Вот решение:
Код
function AddAceToAcl(Name: String; ObjectType: TSeObjectType;
                       User: String; AccessRights: Cardinal): Cardinal;
//DWORD AddAceToAcl (LPTSTR lpObjectName, SE_OBJECT_TYPE ObjectType)
var
 dwRes: Cardinal;
 pOldDACL, pNewDACL: PACL;
 pSD: PSecurityDescriptor;
 ea: TExplicitAccess;
begin
 if (Name = '') then
   begin
     Result := ERROR_INVALID_PARAMETER;
     Exit;
   end;

 // get a pointer to the existing DACL
 dwRes := GetNamedSecurityInfo(PChar(Name), ObjectType,
                               DACL_SECURITY_INFORMATION, nil, nil, @pOldDACL,
                               nil, pSD);

 if dwRes <> ERROR_SUCCESS then
   begin
     result := dwRes;
     Exit;
   end;

 // initialize an EXPLICIT_ACCESS structure to allow access
 ZeroMemory(@ea, SizeOf(TExplicitAccess));
 BuildExplicitAccessWithName(@ea, PChar(User), AccessRights, SET_ACCESS,
                             NO_INHERITANCE);

 // create an new ACL by merging the EXPLICIT_ACCESS structure
 // with the existing DACL
 dwRes := SetEntriesInAcl(1, @ea, pOldDACL, pNewDACL);
 if dwRes = ERROR_SUCCESS then
   begin
     // attach the new ACL as the object's DACL
     dwRes := SetNamedSecurityInfo(PChar(Name), ObjectType,
                                   DACL_SECURITY_INFORMATION, nil, nil,
                                   pNewDACL, nil);
   end;

 result := dwRes;
end;
Это переведено из С. Работает справно. И не только для файлов. Да, и еще... Я тут пользовал JEDI Win32API, так что у Вас могут возникнуть проблемы с типами.

Автор: Romero 25.12.2006, 16:43
Ни в какую не получается ни первым примером, ни от Cheba.
Помогите решить задачу...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)