diff --git a/far/copy.cpp b/far/copy.cpp index 48f55d152e..c2ad1dad25 100644 --- a/far/copy.cpp +++ b/far/copy.cpp @@ -1956,7 +1956,7 @@ COPY_CODES ShellCopy::ShellCopyOneFile( { const auto tmpsd = GetSecurity(Src); - SECURITY_ATTRIBUTES TmpSecAttr{ sizeof(TmpSecAttr), tmpsd? tmpsd.data() : nullptr }; + SECURITY_ATTRIBUTES TmpSecAttr{ sizeof(TmpSecAttr), tmpsd? tmpsd.get() : nullptr }; while (!os::fs::create_directory(strDestPath, tmpsd? &TmpSecAttr : nullptr)) { @@ -2005,7 +2005,7 @@ COPY_CODES ShellCopy::ShellCopyOneFile( const auto sd = GetSecurity(Src); - SECURITY_ATTRIBUTES SecAttr{ sizeof(SecAttr), sd? sd.data() : nullptr }; + SECURITY_ATTRIBUTES SecAttr{ sizeof(SecAttr), sd? sd.get() : nullptr }; if (RPT!=RP_SYMLINKFILE && SrcData.Attributes&FILE_ATTRIBUTE_DIRECTORY) { while (!os::fs::create_directory( @@ -2552,7 +2552,7 @@ bool ShellCopy::ShellCopyFile( { //if (DestAttr!=INVALID_FILE_ATTRIBUTES && !Append) //вот это портит копирование поверх хардлинков //api::DeleteFile(DestName); - SECURITY_ATTRIBUTES SecAttr{ sizeof(SecAttr), sd? sd.data() : nullptr }; + SECURITY_ATTRIBUTES SecAttr{ sizeof(SecAttr), sd? sd.get() : nullptr }; const auto attrs = SrcData.Attributes & ~(Flags & FCOPY_DECRYPTED_DESTINATION? FILE_ATTRIBUTE_ENCRYPTED : 0); const auto IsSystemEncrypted = flags::check_all(attrs, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ENCRYPTED); diff --git a/far/elevation.cpp b/far/elevation.cpp index 633af008e5..0ac23e8af0 100644 --- a/far/elevation.cpp +++ b/far/elevation.cpp @@ -139,7 +139,7 @@ class security_attributes_wrapper return nullptr; auto& Attributes = *m_Attributes; - Attributes.lpSecurityDescriptor = m_Descriptor ? m_Descriptor.data() : nullptr; + Attributes.lpSecurityDescriptor = m_Descriptor ? m_Descriptor.get() : nullptr; return &Attributes; } @@ -148,17 +148,6 @@ class security_attributes_wrapper mutable std::optional m_Attributes; }; -static void WritePipe(const os::handle& Pipe, os::security::descriptor const& Data) -{ - const auto Size = Data.size(); - pipe::write(Pipe, Size); - - if (!Size) - return; - - pipe::write(Pipe, Data.data(), Size); -} - static void WritePipe(const os::handle& Pipe, SECURITY_DESCRIPTOR* Data) { size_t const Size = GetSecurityDescriptorLength(Data); @@ -170,6 +159,11 @@ static void WritePipe(const os::handle& Pipe, SECURITY_DESCRIPTOR* Data) pipe::write(Pipe, Data, Size); } +static void WritePipe(const os::handle& Pipe, os::security::descriptor const& Data) +{ + return WritePipe(Pipe, Data.get()); +} + static void WritePipe(const os::handle& Pipe, SECURITY_ATTRIBUTES* Data) { if (!Data) @@ -196,8 +190,11 @@ static void ReadPipe(const os::handle& Pipe, os::security::descriptor& Data) if (!Size) return; - Data.reset(Size); - pipe::read(Pipe, Data.data(), Size); + Data.reset(static_cast(LocalAlloc(LMEM_FIXED, Size))); + if (!Data) + throw far_exception(far::format(L"LocalAlloc({}): {}"sv, Size, os::last_error())); + + pipe::read(Pipe, Data.get(), Size); } static void ReadPipe(const os::handle& Pipe, security_attributes_wrapper& Data) @@ -373,8 +370,8 @@ static os::handle create_named_pipe(string_view const Name) static bool grant_duplicate_handle() { PACL Acl; - os::memory::local::ptr> Descriptor; - if (const auto Result = GetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, {}, {}, &Acl, {}, &ptr_setter(Descriptor)); Result != ERROR_SUCCESS) + os::security::descriptor Descriptor; + if (const auto Result = GetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, {}, {}, &Acl, {}, std::bit_cast(&ptr_setter(Descriptor))); Result != ERROR_SUCCESS) { LOGWARNING(L"GetSecurityInfo: {}"sv, os::format_error(Result)); return false; @@ -975,7 +972,7 @@ bool elevation::set_file_security(string const& Object, SECURITY_INFORMATION con false, [&] { - return os::fs::low::set_file_security(Object.c_str(), RequestedInformation, Descriptor.data()); + return os::fs::low::set_file_security(Object.c_str(), RequestedInformation, Descriptor.get()); }, [&] { @@ -1329,7 +1326,7 @@ class elevated:noncopyable const auto SecurityInformation = Read(); const auto SecurityDescriptor = Read(); - const auto Result = os::fs::low::set_file_security(Object.c_str(), SecurityInformation, SecurityDescriptor.data()); + const auto Result = os::fs::low::set_file_security(Object.c_str(), SecurityInformation, SecurityDescriptor.get()); Write(os::last_error(), Result); } diff --git a/far/file_io.cpp b/far/file_io.cpp index 75f84c7c5f..a8c856bf94 100644 --- a/far/file_io.cpp +++ b/far/file_io.cpp @@ -91,7 +91,7 @@ void save_file_with_replace(string_view const FileName, os::fs::attributes const // ReplaceFileW handles DAC, but just in case if it can't for whatever reason (see M#3730): SecurityDescriptor = os::fs::get_file_security(FileName, DACL_SECURITY_INFORMATION); if (SecurityDescriptor) - SecurityAttributes.lpSecurityDescriptor = SecurityDescriptor.data(); + SecurityAttributes.lpSecurityDescriptor = SecurityDescriptor.get(); } { diff --git a/far/fileowner.cpp b/far/fileowner.cpp index fc23840826..c48f95e91d 100644 --- a/far/fileowner.cpp +++ b/far/fileowner.cpp @@ -202,7 +202,7 @@ static bool ProcessFileOwner(string_view const Name, function_ref co PSID pOwner; BOOL OwnerDefaulted; - if (!GetSecurityDescriptorOwner(SecurityDescriptor.data(), &pOwner, &OwnerDefaulted)) + if (!GetSecurityDescriptorOwner(SecurityDescriptor.get(), &pOwner, &OwnerDefaulted)) return false; if (!IsValidSid(pOwner)) @@ -269,9 +269,21 @@ bool SetOwnerInternal(const string& Object, const string& Owner) SCOPED_ACTION(os::security::privilege){ SE_TAKE_OWNERSHIP_NAME, SE_RESTORE_NAME }; - const auto Result = SetNamedSecurityInfo(const_cast(Object.c_str()), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, Sid.get(), nullptr, nullptr, nullptr); - SetLastError(Result); - return Result == ERROR_SUCCESS; + if (const auto Result = SetNamedSecurityInfo( + const_cast(Object.c_str()), + SE_FILE_OBJECT, + OWNER_SECURITY_INFORMATION, + Sid.get(), + {}, + {}, + {} + ); Result != ERROR_SUCCESS) + { + SetLastError(Result); + return false; + } + + return true; } bool SetFileOwner(string_view const Object, const string& Owner) diff --git a/far/platform.fs.cpp b/far/platform.fs.cpp index 586d8ece2c..550ec4d8d7 100644 --- a/far/platform.fs.cpp +++ b/far/platform.fs.cpp @@ -1731,33 +1731,79 @@ namespace os::fs security::descriptor get_file_security(const wchar_t* Object, SECURITY_INFORMATION RequestedInformation) { - security::descriptor Result(default_buffer_size); - - if (!os::detail::ApiDynamicReceiver(Result.bytes(), - [&](std::span const Buffer) - { - DWORD LengthNeeded = 0; - if (!::GetFileSecurity(Object, RequestedInformation, static_cast(static_cast(Buffer.data())), static_cast(Buffer.size()), &LengthNeeded)) - return static_cast(LengthNeeded); - return Buffer.size(); - }, - [](size_t ReturnedSize, size_t AllocatedSize) - { - return ReturnedSize > AllocatedSize; - }, - [](std::span) - {} - )) - { - Result.reset(); - } + security::descriptor Descriptor; + + if (const auto Result = GetNamedSecurityInfo( + Object, + SE_FILE_OBJECT, + RequestedInformation, + {}, + {}, + {}, + {}, + std::bit_cast(&ptr_setter(Descriptor) + ) + ); Result != ERROR_SUCCESS) + SetLastError(Result); - return Result; + return Descriptor; } bool set_file_security(const wchar_t* Object, SECURITY_INFORMATION RequestedInformation, SECURITY_DESCRIPTOR* SecurityDescriptor) { - return ::SetFileSecurity(Object, RequestedInformation, SecurityDescriptor) != FALSE; + SECURITY_DESCRIPTOR_CONTROL Control; + DWORD Revision; + if (!GetSecurityDescriptorControl(SecurityDescriptor, &Control, &Revision)) + return false; + + BOOL Defaulted; + + PSID Owner{}; + if (!GetSecurityDescriptorOwner(SecurityDescriptor, &Owner, &Defaulted)) + return false; + + PSID Group{}; + if (!GetSecurityDescriptorGroup(SecurityDescriptor, &Group, &Defaulted)) + return false; + + BOOL Present; + + PACL Dacl{}; + if (!GetSecurityDescriptorDacl(SecurityDescriptor, &Present, &Dacl, &Defaulted)) + return false; + + PACL Sacl{}; + if (!GetSecurityDescriptorSacl(SecurityDescriptor, &Present, &Sacl, &Defaulted)) + return false; + + if (RequestedInformation & DACL_SECURITY_INFORMATION) + { + RequestedInformation |= Control & SE_DACL_PROTECTED? + PROTECTED_DACL_SECURITY_INFORMATION : + UNPROTECTED_DACL_SECURITY_INFORMATION; + } + if (RequestedInformation & SACL_SECURITY_INFORMATION) + { + RequestedInformation |= Control & SE_SACL_PROTECTED? + PROTECTED_SACL_SECURITY_INFORMATION : + UNPROTECTED_SACL_SECURITY_INFORMATION; + } + + if (const auto Result = SetNamedSecurityInfo( + const_cast(Object), + SE_FILE_OBJECT, + RequestedInformation, + Owner, + Group, + Dacl, + Sacl + ); Result != ERROR_SUCCESS) + { + SetLastError(Result); + return false; + } + + return true; } bool reset_file_security(const wchar_t* Object) @@ -1766,9 +1812,21 @@ namespace os::fs if (!InitializeAcl(&EmptyAcl, sizeof(EmptyAcl), ACL_REVISION)) return false; - const auto Result = SetNamedSecurityInfo(const_cast(Object), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION, nullptr, nullptr, &EmptyAcl, nullptr); - SetLastError(Result); - return Result == ERROR_SUCCESS; + if (const auto Result = SetNamedSecurityInfo( + const_cast(Object), + SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION, + {}, + {}, + &EmptyAcl, + {} + ); Result != ERROR_SUCCESS) + { + SetLastError(Result); + return false; + } + + return true; } bool move_to_recycle_bin(string_view const Object) @@ -2296,7 +2354,7 @@ namespace os::fs { const auto NtObject = nt_path(Object); - if (low::set_file_security(NtObject.c_str(), RequestedInformation, SecurityDescriptor.data())) + if (low::set_file_security(NtObject.c_str(), RequestedInformation, SecurityDescriptor.get())) return true; if (ElevationRequired(ELEVATION_MODIFY_REQUEST)) diff --git a/far/platform.security.hpp b/far/platform.security.hpp index d4735edeed..2bb8e69b10 100644 --- a/far/platform.security.hpp +++ b/far/platform.security.hpp @@ -38,6 +38,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Platform: #include "platform.hpp" +#include "platform.memory.hpp" // Common: #include "common/smart_ptr.hpp" @@ -91,7 +92,7 @@ namespace os::security bool m_Changed{}; }; - using descriptor = block_ptr; + using descriptor = memory::local::ptr; } #endif // PLATFORM_SECURITY_HPP_08ED45C7_0FD0_43D5_8838_F9B6F8EFD31C