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