Эксперт
  
Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург
Репутация: 23 Всего: 72
|
Цитата(Alexeis @ 10.12.2013, 10:17 ) | Если получиться, запуль сюда примерчик на делфи. |
Пожалуйста. Функция создает файл с правами: системе, админам, пользователям - полный доступ, "Всем" - только чтение. Код | unit FileAllAccess; interface
function CreateFileWithFullAccessSecurityAttributes(FileName: string): Boolean;
implementation // код честно стырен: // типы и константы - из jedi-api-lib, http://jedi-apilib.sourceforge.net // алгоритм работы - MSDN, http://msdn.microsoft.com/en-us/library/windows/desktop/aa446595(v=vs.85).aspx // ForceDirectoriesEx - подсмотрено (да и, чего греха таить, скопировано) у SysUtils uses Windows, SysUtils, SysConst; {$A+} { record alignment on 4 byte boundaries } {$Z4} { enum size is 4 bytes } // эта супер-директива, которая изначально была // спрятана в jedi-чего-то-там.inc, съела 2 часа моего времени - без нее // возникает глобальный затык на SetEntriesInAclW (некорректный параметр) const SECURITY_NT_AUTHORITY: SID_IDENTIFIER_AUTHORITY = (Value: (0, 0, 0, 0, 0, 5)); SECURITY_WORLD_SID_AUTHORITY: SID_IDENTIFIER_AUTHORITY = (Value: (0, 0, 0, 0, 0, 1));
SECURITY_LOCAL_SYSTEM_RID = $00000012; SECURITY_WORLD_RID = $00000000; SECURITY_BUILTIN_DOMAIN_RID = $00000020; DOMAIN_ALIAS_RID_ADMINS = $00000220; DOMAIN_ALIAS_RID_USERS = $00000221;
NO_INHERITANCE = 0;
type MULTIPLE_TRUSTEE_OPERATION = (NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_IMPERSONATE); TRUSTEE_TYPE = (TRUSTEE_IS_UNKNOWN, TRUSTEE_IS_USER, TRUSTEE_IS_GROUP, TRUSTEE_IS_DOMAIN, TRUSTEE_IS_ALIAS, TRUSTEE_IS_WELL_KNOWN_GROUP, TRUSTEE_IS_DELETED, TRUSTEE_IS_INVALID, TRUSTEE_IS_COMPUTER);
TRUSTEE_FORM = (TRUSTEE_IS_SID, TRUSTEE_IS_NAME, TRUSTEE_BAD_FORM, TRUSTEE_IS_OBJECTS_AND_SID, TRUSTEE_IS_OBJECTS_AND_NAME);
PTRUSTEE_W = ^TRUSTEE_W; TRUSTEE_W = packed record pMultipleTrustee: PTRUSTEE_W; MultipleTrusteeOperation: MULTIPLE_TRUSTEE_OPERATION; TrusteeForm: TRUSTEE_FORM; TrusteeType: TRUSTEE_TYPE; ptstrName: LPWSTR; end;
ACCESS_MODE = (NOT_USED_ACCESS, GRANT_ACCESS, SET_ACCESS, DENY_ACCESS, REVOKE_ACCESS, SET_AUDIT_SUCCESS, SET_AUDIT_FAILURE);
PEXPLICIT_ACCESS_W = ^EXPLICIT_ACCESS_W; EXPLICIT_ACCESS_W = packed record grfAccessPermissions: DWORD; grfAccessMode: ACCESS_MODE; grfInheritance: DWORD; Trustee: TRUSTEE_W; end;
function SetEntriesInAclW(cCountOfExplicitEntries: ULONG; pListOfExplicitEntries: PEXPLICIT_ACCESS_W; OldAcl: PACL; var NewAcl: PACL): DWORD; stdcall; external 'advapi32.dll';
function ForceDirectoriesEx(Dir: string; const sa: TSecurityAttributes): Boolean; var E: EInOutError; begin Result := True; if Dir = '' then begin E := EInOutError.CreateRes(@SCannotCreateDir); E.ErrorCode := 3; raise E; end; Dir := ExcludeTrailingPathDelimiter(Dir); if (Length(Dir) < 3) or DirectoryExists(Dir) or (ExtractFilePath(Dir) = Dir) then Exit; Result := ForceDirectoriesEx(ExtractFilePath(Dir), sa) and CreateDirectory(PChar(Dir), @sa); end;
function CreateFileX(FileName: string; const sa: TSecurityAttributes): Boolean; var hFile: THandle; begin hFile := CreateFile(PChar(FileName), GENERIC_READ or GENERIC_WRITE, 0, @sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); Result := hFile <> INVALID_HANDLE_VALUE; if Result then CloseHandle(hFile); end;
function CreateFileWithFullAccessSecurityAttributes(FileName: string): Boolean; var res: Cardinal;
pSIDSystem: PSID; pSIDAdmins: PSID; pSIDUsers: PSID; pSIDWorld: PSID;
ACL: PACL;
psd: PSecurityDescriptor; sa: TSecurityAttributes;
ea: array [0 .. 3] of EXPLICIT_ACCESS_W;
i: integer; begin Win32Check(AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, pSIDSystem)); try Win32Check(AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, pSIDAdmins)); try Win32Check(AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, pSIDUsers)); try Win32Check(AllocateAndInitializeSid(SECURITY_WORLD_SID_AUTHORITY, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, pSIDWorld)); try FillChar(ea[0], SizeOf(EXPLICIT_ACCESS_W) * Length(ea), 0); i := 0; // "Всем" - только чтение, остальным - полный доступ. // если какой-то блок прав лишний - просто комментим его ea[i].grfAccessPermissions := GENERIC_ALL; ea[i].grfAccessMode := SET_ACCESS; ea[i].grfInheritance := NO_INHERITANCE; ea[i].Trustee.TrusteeForm := TRUSTEE_IS_SID; ea[i].Trustee.TrusteeType := TRUSTEE_IS_GROUP; ea[i].Trustee.ptstrName := pSIDSystem; Inc(i);
ea[i].grfAccessPermissions := GENERIC_ALL; ea[i].grfAccessMode := SET_ACCESS; ea[i].grfInheritance := NO_INHERITANCE; ea[i].Trustee.TrusteeForm := TRUSTEE_IS_SID; ea[i].Trustee.TrusteeType := TRUSTEE_IS_GROUP; ea[i].Trustee.ptstrName := pSIDAdmins; Inc(i);
ea[i].grfAccessPermissions := GENERIC_ALL; ea[i].grfAccessMode := SET_ACCESS; ea[i].grfInheritance := NO_INHERITANCE; ea[i].Trustee.TrusteeForm := TRUSTEE_IS_SID; ea[i].Trustee.TrusteeType := TRUSTEE_IS_GROUP; ea[i].Trustee.ptstrName := pSIDUsers; Inc(i);
ea[i].grfAccessPermissions := GENERIC_READ; ea[i].grfAccessMode := SET_ACCESS; ea[i].grfInheritance := NO_INHERITANCE; ea[i].Trustee.TrusteeForm := TRUSTEE_IS_SID; ea[i].Trustee.TrusteeType := TRUSTEE_IS_WELL_KNOWN_GROUP; ea[i].Trustee.ptstrName := pSIDWorld; Inc(i);
ACL := nil; res := SetEntriesInAclW(i, @ea, nil, ACL); if res <> ERROR_SUCCESS then RaiseLastOSError(res); try psd := AllocMem(SECURITY_DESCRIPTOR_MIN_LENGTH); if not Assigned(psd) then RaiseLastOSError; try if not InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION) then RaiseLastOSError;
if not SetSecurityDescriptorDacl(psd, True, ACL, False) then RaiseLastOSError;
sa.nLength := SizeOf(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor := psd; sa.bInheritHandle := False;
// здесь и только здесь можно безопасно воспользоваться // сформированными правами доступа, а именно - sa. Result:=ForceDirectoriesEx(ExtractFileDir(FileName), sa); if Result then Result:=CreateFileX(FileName, sa); // а вот тут уже лучше не пробовать работать с sa. finally FreeMem(psd); end; finally LocalFree(Cardinal(ACL)); end; finally FreeSid(pSIDWorld); end; finally FreeSid(pSIDUsers); end; finally FreeSid(pSIDAdmins); end; finally FreeSid(pSIDSystem); end; end; end.
|
Это сообщение отредактировал(а) kami - 18.12.2013, 04:02
|