123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // 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 <aclapi.h>
- #include <windows.h>
- #include <string>
- #include "base/check.h"
- #include "base/files/file_path.h"
- #include "base/logging.h"
- #include "base/numerics/checked_math.h"
- #include "base/win/scoped_handle.h"
- #include "base/win/scoped_localalloc.h"
- #include "base/win/win_util.h"
- namespace base {
- namespace win {
- namespace {
- bool AddACEToPath(const FilePath& path,
- const std::vector<Sid>& sids,
- DWORD access_mask,
- DWORD inheritance,
- bool recursive,
- ACCESS_MODE access_mode) {
- DCHECK(!path.empty());
- if (sids.empty())
- return true;
- std::wstring object_name = path.value();
- PSECURITY_DESCRIPTOR sd = nullptr;
- PACL dacl = nullptr;
- // Get the existing DACL.
- DWORD error = ::GetNamedSecurityInfo(object_name.c_str(), SE_FILE_OBJECT,
- DACL_SECURITY_INFORMATION, nullptr,
- nullptr, &dacl, nullptr, &sd);
- if (error != ERROR_SUCCESS) {
- ::SetLastError(error);
- DPLOG(ERROR) << "Failed getting DACL for path \"" << path.value() << "\"";
- return false;
- }
- auto sd_ptr = TakeLocalAlloc(sd);
- std::vector<EXPLICIT_ACCESS> access_entries(sids.size());
- auto entries_interator = access_entries.begin();
- for (const Sid& sid : sids) {
- EXPLICIT_ACCESS& new_access = *entries_interator++;
- new_access.grfAccessMode = access_mode;
- new_access.grfAccessPermissions = access_mask;
- new_access.grfInheritance = inheritance;
- ::BuildTrusteeWithSid(&new_access.Trustee, sid.GetPSID());
- }
- PACL new_dacl = nullptr;
- error = ::SetEntriesInAcl(checked_cast<ULONG>(access_entries.size()),
- access_entries.data(), dacl, &new_dacl);
- if (error != ERROR_SUCCESS) {
- ::SetLastError(error);
- DPLOG(ERROR) << "Failed adding ACEs to DACL for path \"" << path.value()
- << "\"";
- return false;
- }
- auto new_dacl_ptr = TakeLocalAlloc(new_dacl);
- if (recursive) {
- error = ::SetNamedSecurityInfo(&object_name[0], SE_FILE_OBJECT,
- DACL_SECURITY_INFORMATION, nullptr, nullptr,
- new_dacl_ptr.get(), nullptr);
- } else {
- 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;
- }
- error = ::SetSecurityInfo(handle.get(), SE_KERNEL_OBJECT,
- DACL_SECURITY_INFORMATION, nullptr, nullptr,
- new_dacl_ptr.get(), nullptr);
- }
- if (error != ERROR_SUCCESS) {
- ::SetLastError(error);
- DPLOG(ERROR) << "Failed setting DACL for path \"" << path.value() << "\"";
- return false;
- }
- return true;
- }
- } // namespace
- bool GrantAccessToPath(const FilePath& path,
- const std::vector<Sid>& sids,
- DWORD access_mask,
- DWORD inheritance,
- bool recursive) {
- return AddACEToPath(path, sids, access_mask, inheritance, recursive,
- GRANT_ACCESS);
- }
- bool DenyAccessToPath(const FilePath& path,
- const std::vector<Sid>& sids,
- DWORD access_mask,
- DWORD inheritance,
- bool recursive) {
- return AddACEToPath(path, sids, access_mask, inheritance, recursive,
- DENY_ACCESS);
- }
- std::vector<Sid> CloneSidVector(const std::vector<Sid>& sids) {
- std::vector<Sid> clone;
- clone.reserve(sids.size());
- for (const Sid& sid : sids) {
- clone.push_back(sid.Clone());
- }
- return clone;
- }
- void AppendSidVector(std::vector<Sid>& base_sids,
- const std::vector<Sid>& append_sids) {
- for (const Sid& sid : append_sids) {
- base_sids.push_back(sid.Clone());
- }
- }
- } // namespace win
- } // namespace base
|