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