xref: /aosp_15_r20/external/cronet/base/win/security_descriptor.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2022 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 #ifndef BASE_WIN_SECURITY_DESCRIPTOR_H_
6 #define BASE_WIN_SECURITY_DESCRIPTOR_H_
7 
8 #include <stdint.h>
9 
10 #include <optional>
11 #include <string>
12 #include <vector>
13 
14 #include "base/base_export.h"
15 #include "base/files/file_path.h"
16 #include "base/win/access_control_list.h"
17 #include "base/win/access_token.h"
18 #include "base/win/sid.h"
19 #include "base/win/windows_types.h"
20 
21 namespace base::win {
22 
23 // Represents the type of Windows kernel object for reading/writing the security
24 // descriptor.
25 enum class SecurityObjectType {
26   kFile,
27   kRegistry,
28   kWindowStation,
29   kDesktop,
30   kKernel
31 };
32 
33 // Results from the access check.
34 struct AccessCheckResult {
35   // The granted access from the check.
36   ACCESS_MASK granted_access;
37   // The access status. Set to true if the access check was successful.
38   bool access_status;
39 };
40 
41 // This class is used to hold and modify a Windows security descriptor.
42 class BASE_EXPORT SecurityDescriptor {
43  public:
44   class BASE_EXPORT SelfRelative {
45    public:
46     friend SecurityDescriptor;
47 
48     SelfRelative(const SelfRelative&);
49     ~SelfRelative();
50 
size()51     size_t size() const { return sd_.size(); }
get()52     PSECURITY_DESCRIPTOR get() const {
53       return const_cast<uint8_t*>(sd_.data());
54     }
55 
56    private:
57     explicit SelfRelative(std::vector<uint8_t>&& sd);
58 
59     std::vector<uint8_t> sd_;
60   };
61 
62   // Create from an existing security descriptor pointer.
63   // |security_descriptor| The pointer to a self-relative or absolute security
64   // descriptor. This method will copy all security descriptor data.
65   static std::optional<SecurityDescriptor> FromPointer(
66       PSECURITY_DESCRIPTOR security_descriptor);
67 
68   // Create from the security descriptor of an existing file.
69   // |path| the path to the file.
70   // |security_info| indicates what parts to read.
71   static std::optional<SecurityDescriptor> FromFile(
72       const base::FilePath& path,
73       SECURITY_INFORMATION security_info);
74 
75   // Create from the security descriptor of a named Windows object.
76   // |name| the name of the object using the format specified for the
77   // GetNamedSecurityInfo API.
78   // |object_type| specifies the type of object the name represents.
79   // |security_info| indicates what parts to read.
80   static std::optional<SecurityDescriptor> FromName(
81       const std::wstring& name,
82       SecurityObjectType object_type,
83       SECURITY_INFORMATION security_info);
84 
85   // Create from the security descriptor of a kernel object.
86   // |handle| the object handle. It must have READ_CONTROL access.
87   // |object_type| specifies the type of object the handle represents.
88   // |security_info| indicates what parts to read.
89   static std::optional<SecurityDescriptor> FromHandle(
90       HANDLE handle,
91       SecurityObjectType object_type,
92       SECURITY_INFORMATION security_info);
93 
94   // Create from a string representation of a security descriptor.
95   // |sddl| the security descriptor in SDDL format.
96   static std::optional<SecurityDescriptor> FromSddl(const std::wstring& sddl);
97 
98   SecurityDescriptor();
99   SecurityDescriptor(const SecurityDescriptor&) = delete;
100   SecurityDescriptor& operator=(const SecurityDescriptor&) = delete;
101   SecurityDescriptor(SecurityDescriptor&&);
102   SecurityDescriptor& operator=(SecurityDescriptor&&);
103   ~SecurityDescriptor();
104 
105   // Write the security descriptor to a file.
106   // |path| specifies the path to the file.
107   // |security_info| indicates what parts to write.
108   bool WriteToFile(const base::FilePath& path,
109                    SECURITY_INFORMATION security_info) const;
110 
111   // Write the security descriptor to a named kernel object.
112   // |name| the name of the object using the format specified for the
113   // SetNamedSecurityInfo API.
114   // |object_type| specifies the type of object name represents.
115   // |security_info| indicates what parts to write.
116   bool WriteToName(const std::wstring& name,
117                    SecurityObjectType object_type,
118                    SECURITY_INFORMATION security_info) const;
119 
120   // Write the SecurityDescriptor to a kernel object.
121   // |handle| the handle to the object. Must have WRITE_DAC and/or WRITE_OWNER
122   // access depending of the parts specified with |security_info|. |object_type|
123   // specifies the type of object the handle represents. Use kKernel for
124   // undefined types. |security_info| indicates what parts to write.
125   bool WriteToHandle(HANDLE handle,
126                      SecurityObjectType object_type,
127                      SECURITY_INFORMATION security_info) const;
128 
129   // Convert the SecurityDescriptor to an SDDL string.
130   // |security_info| determines what parts are included in the string.
131   std::optional<std::wstring> ToSddl(SECURITY_INFORMATION security_info) const;
132 
133   // Create an reference to the absolute security descriptor of this instance.
134   // |sd| the SECURITY_DESCRIPTOR structure to populate. This is is only valid
135   // as long as this object is in scope and not modified.
136   void ToAbsolute(SECURITY_DESCRIPTOR& sd) const;
137 
138   // Create a self-relative security descriptor in a single buffer.
139   std::optional<SelfRelative> ToSelfRelative() const;
140 
141   // Make a clone of the current security descriptor object.
142   SecurityDescriptor Clone() const;
143 
144   // Set the mandatory label in the security descriptor. Note that calling
145   // this will completely replace the SACL.
146   // |integrity_level| is the integrity level for the label.
147   // |inheritance| specify the flags for inheritance.
148   // |mandatory_policy| is the policy, e.g. SYSTEM_MANDATORY_LABEL_NO_WRITE_UP.
149   bool SetMandatoryLabel(DWORD integrity_level,
150                          DWORD inheritance,
151                          DWORD mandatory_policy);
152 
153   // Set one or more entry in the DACL.
154   // |entries| the list of entries to set in the ACL.
155   // Returns true if successful, false on error, with the Win32 last error set.
156   // If DACL is not present a NULL ACL will be added first.
157   bool SetDaclEntries(const std::vector<ExplicitAccessEntry>& entries);
158 
159   // Set one entry in the DACL.
160   // |sid| the SID for the entry.
161   // |mode| the operation to perform on the ACL, e.g. grant access.
162   // |access_mask| the entries access mask.
163   // |inheritance| inheritance flags.
164   // Returns true if successful, false on
165   // error, with the Win32 last error set.
166   // If DACL is not present a NULL ACL will be added first.
167   bool SetDaclEntry(const Sid& sid,
168                     SecurityAccessMode mode,
169                     DWORD access_mask,
170                     DWORD inheritance);
171 
172   // Set one entry in the DACL.
173   // |known_sid| the known SID for the entry.
174   // |mode| the operation to perform on the ACL, e.g. grant access.
175   // |access_mask| the entries access mask.
176   // |inheritance| inheritance flags.
177   // Returns true if successful, false on
178   // error, with the Win32 last error set.
179   // If DACL is not present a NULL ACL will be added first.
180   bool SetDaclEntry(WellKnownSid known_sid,
181                     SecurityAccessMode mode,
182                     DWORD access_mask,
183                     DWORD inheritance);
184 
185   // Perform an access check for this security descriptor.
186   // |token| specify the impersonation token to check against.
187   // |desired_access| the access desired for the check.
188   // |generic_mapping| the generic mapping for the access check.
189   // Returns the result of the access check. If an empty result is returned the
190   // call to the AccessCheck API failed.
191   std::optional<AccessCheckResult> AccessCheck(
192       const AccessToken& token,
193       ACCESS_MASK desired_access,
194       const GENERIC_MAPPING& generic_mapping);
195 
196   // Perform an access check for this security descriptor.
197   // |token| specify the impersonation token to check against.
198   // |desired_access| the access desired for the check.
199   // |object_type| the object type to determine how to map generic rights. Note
200   // that you can't use kKernel as that doesn't reflect a specific kernel object
201   // type, an empty return will be return if this is used. If you need to access
202   // check an unsupported type use the overload which accepts a manually
203   // configured GENERIC_MAPPING.
204   // Returns the result of the access check. If an empty result is returned the
205   // call to the AccessCheck API failed.
206   std::optional<AccessCheckResult> AccessCheck(const AccessToken& token,
207                                                ACCESS_MASK desired_access,
208                                                SecurityObjectType object_type);
209 
210   // Get, set and clear owner member.
owner()211   const std::optional<Sid>& owner() const { return owner_; }
set_owner(const Sid & owner)212   void set_owner(const Sid& owner) { owner_ = owner.Clone(); }
clear_owner()213   void clear_owner() { owner_ = std::nullopt; }
214 
215   // Get, set and clear group member.
group()216   const std::optional<Sid>& group() const { return group_; }
set_group(const Sid & group)217   void set_group(const Sid& group) { group_ = group.Clone(); }
clear_group()218   void clear_group() { group_ = std::nullopt; }
219 
220   // Get, set and clear dacl member.
dacl()221   const std::optional<AccessControlList>& dacl() const { return dacl_; }
set_dacl(const AccessControlList & dacl)222   void set_dacl(const AccessControlList& dacl) { dacl_ = dacl.Clone(); }
clear_dacl()223   void clear_dacl() { dacl_ = std::nullopt; }
224 
225   // Get and set dacl_protected member.
dacl_protected()226   bool dacl_protected() const { return dacl_protected_; }
set_dacl_protected(bool dacl_protected)227   void set_dacl_protected(bool dacl_protected) {
228     dacl_protected_ = dacl_protected;
229   }
230 
231   // Get, set and clear sacl member.
sacl()232   const std::optional<AccessControlList>& sacl() const { return sacl_; }
set_sacl(const AccessControlList & sacl)233   void set_sacl(const AccessControlList& sacl) { sacl_ = sacl.Clone(); }
clear_sacl()234   void clear_sacl() { sacl_ = std::nullopt; }
235 
236   // Get and set sacl_protected member.
sacl_protected()237   bool sacl_protected() const { return sacl_protected_; }
set_sacl_protected(bool sacl_protected)238   void set_sacl_protected(bool sacl_protected) {
239     sacl_protected_ = sacl_protected;
240   }
241 
242  private:
243   SecurityDescriptor(std::optional<Sid>&& owner,
244                      std::optional<Sid>&& group,
245                      std::optional<AccessControlList>&& dacl,
246                      bool dacl_protected,
247                      std::optional<AccessControlList>&& sacl,
248                      bool sacl_protected);
249 
250   std::optional<Sid> owner_;
251   std::optional<Sid> group_;
252   std::optional<AccessControlList> dacl_;
253   bool dacl_protected_ = false;
254   std::optional<AccessControlList> sacl_;
255   bool sacl_protected_ = false;
256 };
257 
258 }  // namespace base::win
259 
260 #endif  // BASE_WIN_SECURITY_DESCRIPTOR_H_
261