tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

access_token.h (13127B)


      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 #ifndef BASE_WIN_ACCESS_TOKEN_H_
      6 #define BASE_WIN_ACCESS_TOKEN_H_
      7 
      8 #include <memory>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/base_export.h"
     13 #include "base/win/access_control_list.h"
     14 #include "base/win/scoped_handle.h"
     15 #include "base/win/sid.h"
     16 #include "base/win/windows_types.h"
     17 #include "third_party/abseil-cpp/absl/types/optional.h"
     18 
     19 namespace base::win {
     20 
     21 // Impersonation level for the token.
     22 enum class SecurityImpersonationLevel {
     23  kAnonymous,
     24  kIdentification,
     25  kImpersonation,
     26  kDelegation
     27 };
     28 
     29 // This class is used to access the information for a Windows access token.
     30 class BASE_EXPORT AccessToken {
     31 public:
     32  // This class represents an access token group.
     33  class BASE_EXPORT Group {
     34   public:
     35    // Get the group SID.
     36    const Sid& GetSid() const { return sid_; }
     37    // Get the group attribute flags.
     38    DWORD GetAttributes() const { return attributes_; }
     39    // Returns true if the group is an integrity level.
     40    bool IsIntegrity() const;
     41    // Returns true if the group is enabled.
     42    bool IsEnabled() const;
     43    // Returns true if the group is deny only.
     44    bool IsDenyOnly() const;
     45    // Returns true if the group is the logon ID.
     46    bool IsLogonId() const;
     47 
     48    Group(Sid&& sid, DWORD attributes);
     49    Group(Group&&);
     50    ~Group();
     51 
     52   private:
     53    Sid sid_;
     54    DWORD attributes_;
     55  };
     56 
     57  // This class represents an access token privilege.
     58  class BASE_EXPORT Privilege {
     59   public:
     60    // Get the privilege LUID.
     61    CHROME_LUID GetLuid() const { return luid_; }
     62    // Get the privilege attribute flags.
     63    DWORD GetAttributes() const { return attributes_; }
     64    // Get the name of the privilege.
     65    std::wstring GetName() const;
     66    // Returns true if the privilege is enabled.
     67    bool IsEnabled() const;
     68 
     69    Privilege(CHROME_LUID luid, DWORD attributes);
     70 
     71   private:
     72    CHROME_LUID luid_;
     73    DWORD attributes_;
     74  };
     75 
     76  // Creates an AccessToken object from a token handle.
     77  // |token| the token handle. This handle will be duplicated for TOKEN_QUERY
     78  // access, therefore the caller must be granted that access to the token
     79  // object. The AccessToken object owns its own copy of the token handle so
     80  // the original can be closed.
     81  // |desired_access| specifies additional access for the token handle,
     82  // TOKEN_QUERY will always be requested.
     83  static absl::optional<AccessToken> FromToken(HANDLE token,
     84                                               ACCESS_MASK desired_access = 0);
     85 
     86  // Creates an AccessToken object from an existing token handle.
     87  // |token| the token handle. The AccessToken object will take ownership of
     88  // this handle without duplicating it. It must have been opened with at least
     89  // TOKEN_QUERY access to succeed.
     90  static absl::optional<AccessToken> FromToken(ScopedHandle&& token);
     91 
     92  // Creates an AccessToken object from a process handle.
     93  // |process| the process handle. The handle needs to have
     94  // PROCESS_QUERY_LIMITED_INFORMATION access to the handle and TOKEN_QUERY
     95  // access to the token object.
     96  // |impersonation| if true then the process token will be duplicated to an
     97  // impersonation token. This allows you to call the IsMember API which
     98  // requires an impersonation token. To duplicate TOKEN_DUPLICATE access is
     99  // required.
    100  // |desired_access| specifies additional access for the token handle,
    101  // TOKEN_QUERY will always be requested.
    102  static absl::optional<AccessToken> FromProcess(
    103      HANDLE process,
    104      bool impersonation = false,
    105      ACCESS_MASK desired_access = 0);
    106 
    107  // Creates an AccessToken object for the current process.
    108  // |impersonation| if true then the process token will be duplicated to an
    109  // impersonation token. This allows you to call the IsMember API which
    110  // requires an impersonation token. To duplicate TOKEN_DUPLICATE access is
    111  // required.
    112  // |desired_access| specifies additional access for the token handle,
    113  // TOKEN_QUERY will always be requested.
    114  static absl::optional<AccessToken> FromCurrentProcess(
    115      bool impersonation = false,
    116      ACCESS_MASK desired_access = 0);
    117 
    118  // Creates an AccessToken object from a thread handle. The thread must be
    119  // impersonating a token for this to succeed.
    120  // |thread| the thread handle. The handle needs to have
    121  // THREAD_QUERY_LIMITED_INFORMATION access and TOKEN_QUERY access to the
    122  // token object.
    123  // |open_as_self| open the token using the process token rather than the
    124  // current thread's impersonated token.
    125  // If the thread isn't impersonating it will return an empty value and the
    126  // Win32 last error code will be ERROR_NO_TOKEN.
    127  // |desired_access| specifies additional access for the token handle,
    128  // TOKEN_QUERY will always be requested.
    129  static absl::optional<AccessToken> FromThread(HANDLE thread,
    130                                                bool open_as_self = true,
    131                                                ACCESS_MASK desired_access = 0);
    132 
    133  // Creates an AccessToken object from the current thread. The thread must be
    134  // impersonating a token for this to succeed.
    135  // |open_as_self| open the thread handle using the process token rather
    136  // than the current thread's impersonated token.
    137  // If the thread isn't impersonating it will return an empty value and the
    138  // Win32 last error code will be ERROR_NO_TOKEN.
    139  // |desired_access| specifies additional access for the token handle,
    140  // TOKEN_QUERY will always be requested.
    141  static absl::optional<AccessToken> FromCurrentThread(
    142      bool open_as_self = true,
    143      ACCESS_MASK desired_access = 0);
    144 
    145  // Creates an AccessToken object for the current thread's effective token.
    146  // If the thread is impersonating then it'll try and open the thread token,
    147  // otherwise it'll open the process token.
    148  // |desired_access| specifies additional access for the token handle,
    149  // TOKEN_QUERY will always be requested.
    150  static absl::optional<AccessToken> FromEffective(
    151      ACCESS_MASK desired_access = 0);
    152 
    153  AccessToken(const AccessToken&) = delete;
    154  AccessToken& operator=(const AccessToken&) = delete;
    155  AccessToken(AccessToken&&);
    156  AccessToken& operator=(AccessToken&&);
    157  ~AccessToken();
    158 
    159  // Get the token's user SID.
    160  Sid User() const;
    161 
    162  // Get the token's user group.
    163  Group UserGroup() const;
    164 
    165  // Get the token's owner SID. This can be different to the user SID, it's
    166  // used as the default owner for new secured objects.
    167  Sid Owner() const;
    168 
    169  // Get the token's primary group SID.
    170  Sid PrimaryGroup() const;
    171 
    172  // Get the token logon SID. Returns an empty value if the token doesn't have
    173  // a logon SID. If the logon SID doesn't exist then the Win32 last error code
    174  // will be ERROR_NOT_FOUND.
    175  absl::optional<Sid> LogonId() const;
    176 
    177  // Get the token's integrity level. Returns MAXDWORD if the token doesn't
    178  // have an integrity level.
    179  DWORD IntegrityLevel() const;
    180 
    181  // Set the token's integrity level. Token needs to have been opened with
    182  // TOKEN_ADJUST_DEFAULT access.
    183  bool SetIntegrityLevel(DWORD integrity_level);
    184 
    185  // Get the token's session ID. Returns MAXDWORD if the token if the session
    186  // ID can't be queried.
    187  DWORD SessionId() const;
    188 
    189  // The token's group list.
    190  std::vector<Group> Groups() const;
    191 
    192  // Get whether the token is a restricted.
    193  bool IsRestricted() const;
    194 
    195  // The token's restricted SIDs list. If not a restricted token this will
    196  // return an empty vector.
    197  std::vector<Group> RestrictedSids() const;
    198 
    199  // Get whether the token is an appcontainer.
    200  bool IsAppContainer() const;
    201 
    202  // Get the token's appcontainer SID. If not an appcontainer token this will
    203  // return an empty value.
    204  absl::optional<Sid> AppContainerSid() const;
    205 
    206  // The token's capabilities. If not an appcontainer token this will return an
    207  // empty vector.
    208  std::vector<Group> Capabilities() const;
    209 
    210  // Get the UAC linked token.
    211  absl::optional<AccessToken> LinkedToken() const;
    212 
    213  // Get the default DACL for the token. Returns an empty value on error.
    214  absl::optional<AccessControlList> DefaultDacl() const;
    215 
    216  // Set the default DACL of the token. Token needs to have been opened with
    217  // TOKEN_ADJUST_DEFAULT access.
    218  bool SetDefaultDacl(const AccessControlList& default_dacl);
    219 
    220  // Get the token's ID.
    221  CHROME_LUID Id() const;
    222 
    223  // Get the token's authentication ID.
    224  CHROME_LUID AuthenticationId() const;
    225 
    226  // Get the token's privileges.
    227  std::vector<Privilege> Privileges() const;
    228 
    229  // Get whether the token is elevated.
    230  bool IsElevated() const;
    231 
    232  // Checks if the sid is a member of the token's groups. The token must be
    233  // an impersonation token rather than a primary token. If the token is not an
    234  // impersonation token then it returns false and the Win32 last error will be
    235  // set to ERROR_NO_IMPERSONATION_TOKEN.
    236  bool IsMember(const Sid& sid) const;
    237 
    238  // Checks if the well known sid is a member of the token's groups. The token
    239  // must be an impersonation token rather than a primary token. If the token
    240  // is not an impersonation token then it returns false and the Win32 last
    241  // error will be set to ERROR_NO_IMPERSONATION_TOKEN.
    242  bool IsMember(WellKnownSid known_sid) const;
    243 
    244  // Checks if the token is an impersonation token. If false then it's a primary
    245  // token.
    246  bool IsImpersonation() const;
    247 
    248  // Checks if the token can only be used for identification. This is based on
    249  // the security impersonation level of the token. If the level is less than
    250  // or equal to SecurityIdentification this function returns true. Always
    251  // returns false for a primary token.
    252  bool IsIdentification() const;
    253 
    254  // Get the current impersonation level. If the token is a primary token
    255  // the function returns kImpersonation.
    256  SecurityImpersonationLevel ImpersonationLevel() const;
    257 
    258  // Duplicate the token to a new primary token.
    259  // |desired_access| specifies additional access for the token handle.
    260  // TOKEN_QUERY will always be requested.
    261  // The original token must have TOKEN_DUPLICATE access to successfully
    262  // duplicate the token.
    263  absl::optional<AccessToken> DuplicatePrimary(
    264      ACCESS_MASK desired_access = 0) const;
    265 
    266  // Duplicate the token to a new impersonation token.
    267  // |impersonation_level| specifies the impersonation level for the token.
    268  // |desired_access| specifies additional access for the token handle.
    269  // TOKEN_QUERY will always be requested.
    270  // The original token must have TOKEN_DUPLICATE access to successfully
    271  // duplicate the token.
    272  absl::optional<AccessToken> DuplicateImpersonation(
    273      SecurityImpersonationLevel impersonation_level =
    274          SecurityImpersonationLevel::kImpersonation,
    275      ACCESS_MASK desired_access = 0) const;
    276 
    277  // Create a new restricted token from this token.
    278  // |flags| can be set to a combination of DISABLE_MAX_PRIVILEGE,
    279  // SANDBOX_INERT, LUA_TOKEN and WRITE_RESTRICTED.
    280  // |sids_to_disable| is the list of SIDs to disable in the token.
    281  // |privileges_to_delete| is the names of the privileges to delete.
    282  // |sids_to_restrict| is the list of SIDs to add as restricted SIDs.
    283  // |desired_access| specifies additional access for the token handle.
    284  // The token needs to be opened with TOKEN_DUPLICATE access.
    285  absl::optional<AccessToken> CreateRestricted(
    286      DWORD flags,
    287      const std::vector<Sid>& sids_to_disable,
    288      const std::vector<std::wstring>& privileges_to_delete,
    289      const std::vector<Sid>& sids_to_restrict,
    290      ACCESS_MASK desired_access = 0) const;
    291 
    292  // Create a new AppContainer primary token from this token.
    293  // |app_container_sid| the AppContainer package SID.
    294  // |capabilities| the list of AppContainer capabilities.
    295  // |desired_access| specifies additional access for the token handle.
    296  // The token needs to be opened with TOKEN_DUPLICATE access.
    297  absl::optional<AccessToken> CreateAppContainer(
    298      const Sid& appcontainer_sid,
    299      const std::vector<Sid>& capabilities,
    300      ACCESS_MASK desired_access = 0) const;
    301 
    302  // Enable or disable a privilege.
    303  // |name| the name of the privilege to change.
    304  // |enable| specify whether to enable or disable the privilege.
    305  // Returns the previous enable state of the privilege, or nullopt if failed.
    306  // The token must be opened with TOKEN_ADJUST_PRIVILEGES access.
    307  absl::optional<bool> SetPrivilege(const std::wstring& name, bool enable);
    308 
    309  // Remove a privilege permanently from the token.
    310  // |name| the name of the privilege to remove.
    311  // Returns true if successfully removed the privilege.
    312  // The token must be opened with TOKEN_ADJUST_PRIVILEGES access.
    313  bool RemovePrivilege(const std::wstring& name);
    314 
    315  // Indicates if the AccessToken object is valid.
    316  bool is_valid() const;
    317 
    318  // Get the underlying token handle.
    319  HANDLE get() const;
    320 
    321  // Take ownership of the underlying token handle. Once released no other
    322  // methods on this object should be called.
    323  ScopedHandle release();
    324 
    325 private:
    326  explicit AccessToken(HANDLE token);
    327  ScopedHandle token_;
    328 };
    329 
    330 }  // namespace base::win
    331 
    332 #endif  // BASE_WIN_ACCESS_TOKEN_H_