• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/win/access_control_list.h"
14 #include "base/win/scoped_handle.h"
15 #include "base/win/security_descriptor.h"
16 #include "third_party/abseil-cpp/absl/types/optional.h"
17 
18 namespace base {
19 namespace win {
20 
21 namespace {
22 
AddACEToPath(const FilePath & path,const std::vector<Sid> & sids,DWORD access_mask,DWORD inheritance,bool recursive,SecurityAccessMode access_mode)23 bool AddACEToPath(const FilePath& path,
24                   const std::vector<Sid>& sids,
25                   DWORD access_mask,
26                   DWORD inheritance,
27                   bool recursive,
28                   SecurityAccessMode access_mode) {
29   DCHECK(!path.empty());
30   if (sids.empty()) {
31     return true;
32   }
33 
34   absl::optional<SecurityDescriptor> sd =
35       SecurityDescriptor::FromFile(path, DACL_SECURITY_INFORMATION);
36   if (!sd) {
37     return false;
38   }
39 
40   std::vector<ExplicitAccessEntry> entries;
41   for (const Sid& sid : sids) {
42     entries.emplace_back(sid, access_mode, access_mask, inheritance);
43   }
44 
45   if (!sd->SetDaclEntries(entries)) {
46     return false;
47   }
48 
49   if (recursive) {
50     return sd->WriteToFile(path, DACL_SECURITY_INFORMATION);
51   }
52 
53   ScopedHandle handle(::CreateFile(path.value().c_str(), WRITE_DAC, 0, nullptr,
54                                    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS,
55                                    nullptr));
56   if (!handle.is_valid()) {
57     DPLOG(ERROR) << "Failed opening path \"" << path.value()
58                  << "\" to write DACL";
59     return false;
60   }
61   return sd->WriteToHandle(handle.get(), SecurityObjectType::kKernel,
62                            DACL_SECURITY_INFORMATION);
63 }
64 
65 }  // namespace
66 
GrantAccessToPath(const FilePath & path,const std::vector<Sid> & sids,DWORD access_mask,DWORD inheritance,bool recursive)67 bool GrantAccessToPath(const FilePath& path,
68                        const std::vector<Sid>& sids,
69                        DWORD access_mask,
70                        DWORD inheritance,
71                        bool recursive) {
72   return AddACEToPath(path, sids, access_mask, inheritance, recursive,
73                       SecurityAccessMode::kGrant);
74 }
75 
DenyAccessToPath(const FilePath & path,const std::vector<Sid> & sids,DWORD access_mask,DWORD inheritance,bool recursive)76 bool DenyAccessToPath(const FilePath& path,
77                       const std::vector<Sid>& sids,
78                       DWORD access_mask,
79                       DWORD inheritance,
80                       bool recursive) {
81   return AddACEToPath(path, sids, access_mask, inheritance, recursive,
82                       SecurityAccessMode::kDeny);
83 }
84 
CloneSidVector(const std::vector<Sid> & sids)85 std::vector<Sid> CloneSidVector(const std::vector<Sid>& sids) {
86   std::vector<Sid> clone;
87   clone.reserve(sids.size());
88   for (const Sid& sid : sids) {
89     clone.push_back(sid.Clone());
90   }
91   return clone;
92 }
93 
AppendSidVector(std::vector<Sid> & base_sids,const std::vector<Sid> & append_sids)94 void AppendSidVector(std::vector<Sid>& base_sids,
95                      const std::vector<Sid>& append_sids) {
96   for (const Sid& sid : append_sids) {
97     base_sids.push_back(sid.Clone());
98   }
99 }
100 
GetGrantedAccess(HANDLE handle)101 absl::optional<ACCESS_MASK> GetGrantedAccess(HANDLE handle) {
102   PUBLIC_OBJECT_BASIC_INFORMATION basic_info = {};
103   if (!NT_SUCCESS(::NtQueryObject(handle, ObjectBasicInformation, &basic_info,
104                                   sizeof(basic_info), nullptr))) {
105     return absl::nullopt;
106   }
107   return basic_info.GrantedAccess;
108 }
109 
110 }  // namespace win
111 }  // namespace base
112