// Copyright 2021 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/win/security_util.h" #include #include #include "base/check.h" #include "base/files/file_path.h" #include "base/logging.h" #include "base/win/access_control_list.h" #include "base/win/scoped_handle.h" #include "base/win/security_descriptor.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace base { namespace win { namespace { bool AddACEToPath(const FilePath& path, const std::vector& sids, DWORD access_mask, DWORD inheritance, bool recursive, SecurityAccessMode access_mode) { DCHECK(!path.empty()); if (sids.empty()) { return true; } absl::optional sd = SecurityDescriptor::FromFile(path, DACL_SECURITY_INFORMATION); if (!sd) { return false; } std::vector entries; for (const Sid& sid : sids) { entries.emplace_back(sid, access_mode, access_mask, inheritance); } if (!sd->SetDaclEntries(entries)) { return false; } if (recursive) { return sd->WriteToFile(path, DACL_SECURITY_INFORMATION); } ScopedHandle handle(::CreateFile(path.value().c_str(), WRITE_DAC, 0, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr)); if (!handle.is_valid()) { DPLOG(ERROR) << "Failed opening path \"" << path.value() << "\" to write DACL"; return false; } return sd->WriteToHandle(handle.get(), SecurityObjectType::kKernel, DACL_SECURITY_INFORMATION); } } // namespace bool GrantAccessToPath(const FilePath& path, const std::vector& sids, DWORD access_mask, DWORD inheritance, bool recursive) { return AddACEToPath(path, sids, access_mask, inheritance, recursive, SecurityAccessMode::kGrant); } bool DenyAccessToPath(const FilePath& path, const std::vector& sids, DWORD access_mask, DWORD inheritance, bool recursive) { return AddACEToPath(path, sids, access_mask, inheritance, recursive, SecurityAccessMode::kDeny); } std::vector CloneSidVector(const std::vector& sids) { std::vector clone; clone.reserve(sids.size()); for (const Sid& sid : sids) { clone.push_back(sid.Clone()); } return clone; } void AppendSidVector(std::vector& base_sids, const std::vector& append_sids) { for (const Sid& sid : append_sids) { base_sids.push_back(sid.Clone()); } } absl::optional GetGrantedAccess(HANDLE handle) { PUBLIC_OBJECT_BASIC_INFORMATION basic_info = {}; if (!NT_SUCCESS(::NtQueryObject(handle, ObjectBasicInformation, &basic_info, sizeof(basic_info), nullptr))) { return absl::nullopt; } return basic_info.GrantedAccess; } } // namespace win } // namespace base