security_util.cc (3443B)
1 // Copyright 2021 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/win/security_util.h" 6 7 #include <windows.h> 8 #include <winternl.h> 9 10 #include "base/check.h" 11 #include "base/files/file_path.h" 12 #include "base/logging.h" 13 #include "base/threading/scoped_blocking_call.h" 14 #include "base/win/access_control_list.h" 15 #include "base/win/scoped_handle.h" 16 #include "base/win/security_descriptor.h" 17 #include "third_party/abseil-cpp/absl/types/optional.h" 18 19 namespace base { 20 namespace win { 21 22 namespace { 23 24 bool AddACEToPath(const FilePath& path, 25 const std::vector<Sid>& sids, 26 DWORD access_mask, 27 DWORD inheritance, 28 bool recursive, 29 SecurityAccessMode access_mode) { 30 DCHECK(!path.empty()); 31 if (sids.empty()) { 32 return true; 33 } 34 base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, 35 base::BlockingType::MAY_BLOCK); 36 37 absl::optional<SecurityDescriptor> sd = 38 SecurityDescriptor::FromFile(path, DACL_SECURITY_INFORMATION); 39 if (!sd) { 40 return false; 41 } 42 43 std::vector<ExplicitAccessEntry> entries; 44 for (const Sid& sid : sids) { 45 entries.emplace_back(sid, access_mode, access_mask, inheritance); 46 } 47 48 if (!sd->SetDaclEntries(entries)) { 49 return false; 50 } 51 52 if (recursive) { 53 return sd->WriteToFile(path, DACL_SECURITY_INFORMATION); 54 } 55 56 ScopedHandle handle(::CreateFile(path.value().c_str(), WRITE_DAC, 0, nullptr, 57 OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 58 nullptr)); 59 if (!handle.is_valid()) { 60 DPLOG(ERROR) << "Failed opening path \"" << path.value() 61 << "\" to write DACL"; 62 return false; 63 } 64 return sd->WriteToHandle(handle.get(), SecurityObjectType::kKernel, 65 DACL_SECURITY_INFORMATION); 66 } 67 68 } // namespace 69 70 bool GrantAccessToPath(const FilePath& path, 71 const std::vector<Sid>& sids, 72 DWORD access_mask, 73 DWORD inheritance, 74 bool recursive) { 75 return AddACEToPath(path, sids, access_mask, inheritance, recursive, 76 SecurityAccessMode::kGrant); 77 } 78 79 bool DenyAccessToPath(const FilePath& path, 80 const std::vector<Sid>& sids, 81 DWORD access_mask, 82 DWORD inheritance, 83 bool recursive) { 84 return AddACEToPath(path, sids, access_mask, inheritance, recursive, 85 SecurityAccessMode::kDeny); 86 } 87 88 std::vector<Sid> CloneSidVector(const std::vector<Sid>& sids) { 89 std::vector<Sid> clone; 90 clone.reserve(sids.size()); 91 for (const Sid& sid : sids) { 92 clone.push_back(sid.Clone()); 93 } 94 return clone; 95 } 96 97 void AppendSidVector(std::vector<Sid>& base_sids, 98 const std::vector<Sid>& append_sids) { 99 for (const Sid& sid : append_sids) { 100 base_sids.push_back(sid.Clone()); 101 } 102 } 103 104 absl::optional<ACCESS_MASK> GetGrantedAccess(HANDLE handle) { 105 PUBLIC_OBJECT_BASIC_INFORMATION basic_info = {}; 106 if (!NT_SUCCESS(::NtQueryObject(handle, ObjectBasicInformation, &basic_info, 107 sizeof(basic_info), nullptr))) { 108 return absl::nullopt; 109 } 110 return basic_info.GrantedAccess; 111 } 112 113 } // namespace win 114 } // namespace base