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_ACCESS_CONTROL_LIST_H_ 6 #define BASE_WIN_ACCESS_CONTROL_LIST_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 #include <vector> 12 13 #include "base/base_export.h" 14 #include "base/win/sid.h" 15 #include "base/win/windows_types.h" 16 #include "third_party/abseil-cpp/absl/types/optional.h" 17 18 namespace base::win { 19 20 // Represents the type of access operation to perform on an ACL. 21 enum class SecurityAccessMode { kGrant, kSet, kDeny, kRevoke }; 22 23 // Class to represent an entry to modify the ACL. 24 class BASE_EXPORT ExplicitAccessEntry { 25 public: 26 ExplicitAccessEntry(const Sid& sid, 27 SecurityAccessMode mode, 28 DWORD access_mask, 29 DWORD inheritance); 30 ExplicitAccessEntry(WellKnownSid known_sid, 31 SecurityAccessMode mode, 32 DWORD access_mask, 33 DWORD inheritance); 34 ExplicitAccessEntry(const ExplicitAccessEntry&) = delete; 35 ExplicitAccessEntry& operator=(const ExplicitAccessEntry&) = delete; 36 ExplicitAccessEntry(ExplicitAccessEntry&&); 37 ExplicitAccessEntry& operator=(ExplicitAccessEntry&&); 38 ~ExplicitAccessEntry(); 39 sid()40 const Sid& sid() const { return sid_; } mode()41 SecurityAccessMode mode() const { return mode_; } access_mask()42 DWORD access_mask() const { return access_mask_; } inheritance()43 DWORD inheritance() const { return inheritance_; } 44 // Clones the entry. 45 ExplicitAccessEntry Clone() const; 46 47 private: 48 Sid sid_; 49 SecurityAccessMode mode_; 50 DWORD access_mask_; 51 DWORD inheritance_; 52 }; 53 54 // This class is used to hold and modify Windows ACLs. An AccessControlList 55 // object can contain a null ACL which grants everyone access to a resource. A 56 // null ACL is distinct from an empty ACL which grants no-one access. An empty 57 // ACL is the default when constructing a new instance. 58 class BASE_EXPORT AccessControlList { 59 public: 60 // Create from an existing ACL pointer. 61 // |acl| The ACL pointer. Passing nullptr will create a null ACL. 62 static absl::optional<AccessControlList> FromPACL(ACL* acl); 63 64 // Create an AccessControlList from a mandatory label. 65 // |integrity_level| is the integrity level for the label. 66 // |inheritance| inheritance flags. 67 // |mandatory_policy| is the policy, e.g. SYSTEM_MANDATORY_LABEL_NO_WRITE_UP. 68 static absl::optional<AccessControlList> FromMandatoryLabel( 69 DWORD integrity_level, 70 DWORD inheritance, 71 DWORD mandatory_policy); 72 73 AccessControlList(); 74 AccessControlList(const AccessControlList&) = delete; 75 AccessControlList& operator=(const AccessControlList&) = delete; 76 AccessControlList(AccessControlList&&); 77 AccessControlList& operator=(AccessControlList&&); 78 ~AccessControlList(); 79 80 // Set one or more entry in the ACL. 81 // |entries| the list of entries to set in the ACL. 82 // Returns true if successful, false on error, with the Win32 last error set. 83 bool SetEntries(const std::vector<ExplicitAccessEntry>& entries); 84 85 // Set one entry in the ACL. 86 // |sid| the SID for the entry. 87 // |mode| the operation to perform on the ACL, e.g. grant access. 88 // |access_mask| the entries access mask. 89 // |inheritance| inheritance flags. 90 // Returns true if successful, false on error, with the Win32 last error set. 91 bool SetEntry(const Sid& sid, 92 SecurityAccessMode mode, 93 DWORD access_mask, 94 DWORD inheritance); 95 96 // Make a clone of the current AccessControlList object. 97 AccessControlList Clone() const; 98 99 // Clear all entries in the AccessControlList. 100 void Clear(); 101 102 // Returns the AccessControlList as a ACL*. The AccessControlList object 103 // retains owenership of the pointer. This can return nullptr if the ACL is 104 // null. get()105 ACL* get() const { return reinterpret_cast<ACL*>(acl_.get()); } 106 107 // Returns whether the AccessControlList is considered a null ACL. is_null()108 bool is_null() const { return !acl_; } 109 110 private: 111 explicit AccessControlList(const ACL* acl); 112 std::unique_ptr<uint8_t[]> acl_; 113 }; 114 115 } // namespace base::win 116 117 #endif // BASE_WIN_ACCESS_CONTROL_LIST_H_ 118