security_util.cc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/win/security_util.h"
  5. #include <aclapi.h>
  6. #include <windows.h>
  7. #include <string>
  8. #include "base/check.h"
  9. #include "base/files/file_path.h"
  10. #include "base/logging.h"
  11. #include "base/numerics/checked_math.h"
  12. #include "base/win/scoped_handle.h"
  13. #include "base/win/scoped_localalloc.h"
  14. #include "base/win/win_util.h"
  15. namespace base {
  16. namespace win {
  17. namespace {
  18. bool AddACEToPath(const FilePath& path,
  19. const std::vector<Sid>& sids,
  20. DWORD access_mask,
  21. DWORD inheritance,
  22. bool recursive,
  23. ACCESS_MODE access_mode) {
  24. DCHECK(!path.empty());
  25. if (sids.empty())
  26. return true;
  27. std::wstring object_name = path.value();
  28. PSECURITY_DESCRIPTOR sd = nullptr;
  29. PACL dacl = nullptr;
  30. // Get the existing DACL.
  31. DWORD error = ::GetNamedSecurityInfo(object_name.c_str(), SE_FILE_OBJECT,
  32. DACL_SECURITY_INFORMATION, nullptr,
  33. nullptr, &dacl, nullptr, &sd);
  34. if (error != ERROR_SUCCESS) {
  35. ::SetLastError(error);
  36. DPLOG(ERROR) << "Failed getting DACL for path \"" << path.value() << "\"";
  37. return false;
  38. }
  39. auto sd_ptr = TakeLocalAlloc(sd);
  40. std::vector<EXPLICIT_ACCESS> access_entries(sids.size());
  41. auto entries_interator = access_entries.begin();
  42. for (const Sid& sid : sids) {
  43. EXPLICIT_ACCESS& new_access = *entries_interator++;
  44. new_access.grfAccessMode = access_mode;
  45. new_access.grfAccessPermissions = access_mask;
  46. new_access.grfInheritance = inheritance;
  47. ::BuildTrusteeWithSid(&new_access.Trustee, sid.GetPSID());
  48. }
  49. PACL new_dacl = nullptr;
  50. error = ::SetEntriesInAcl(checked_cast<ULONG>(access_entries.size()),
  51. access_entries.data(), dacl, &new_dacl);
  52. if (error != ERROR_SUCCESS) {
  53. ::SetLastError(error);
  54. DPLOG(ERROR) << "Failed adding ACEs to DACL for path \"" << path.value()
  55. << "\"";
  56. return false;
  57. }
  58. auto new_dacl_ptr = TakeLocalAlloc(new_dacl);
  59. if (recursive) {
  60. error = ::SetNamedSecurityInfo(&object_name[0], SE_FILE_OBJECT,
  61. DACL_SECURITY_INFORMATION, nullptr, nullptr,
  62. new_dacl_ptr.get(), nullptr);
  63. } else {
  64. ScopedHandle handle(::CreateFile(path.value().c_str(), WRITE_DAC, 0,
  65. nullptr, OPEN_EXISTING,
  66. FILE_FLAG_BACKUP_SEMANTICS, nullptr));
  67. if (!handle.is_valid()) {
  68. DPLOG(ERROR) << "Failed opening path \"" << path.value()
  69. << "\" to write DACL";
  70. return false;
  71. }
  72. error = ::SetSecurityInfo(handle.get(), SE_KERNEL_OBJECT,
  73. DACL_SECURITY_INFORMATION, nullptr, nullptr,
  74. new_dacl_ptr.get(), nullptr);
  75. }
  76. if (error != ERROR_SUCCESS) {
  77. ::SetLastError(error);
  78. DPLOG(ERROR) << "Failed setting DACL for path \"" << path.value() << "\"";
  79. return false;
  80. }
  81. return true;
  82. }
  83. } // namespace
  84. bool GrantAccessToPath(const FilePath& path,
  85. const std::vector<Sid>& sids,
  86. DWORD access_mask,
  87. DWORD inheritance,
  88. bool recursive) {
  89. return AddACEToPath(path, sids, access_mask, inheritance, recursive,
  90. GRANT_ACCESS);
  91. }
  92. bool DenyAccessToPath(const FilePath& path,
  93. const std::vector<Sid>& sids,
  94. DWORD access_mask,
  95. DWORD inheritance,
  96. bool recursive) {
  97. return AddACEToPath(path, sids, access_mask, inheritance, recursive,
  98. DENY_ACCESS);
  99. }
  100. std::vector<Sid> CloneSidVector(const std::vector<Sid>& sids) {
  101. std::vector<Sid> clone;
  102. clone.reserve(sids.size());
  103. for (const Sid& sid : sids) {
  104. clone.push_back(sid.Clone());
  105. }
  106. return clone;
  107. }
  108. void AppendSidVector(std::vector<Sid>& base_sids,
  109. const std::vector<Sid>& append_sids) {
  110. for (const Sid& sid : append_sids) {
  111. base_sids.push_back(sid.Clone());
  112. }
  113. }
  114. } // namespace win
  115. } // namespace base