| // Copyright 2010 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SANDBOX_WIN_SRC_RESTRICTED_TOKEN_H_ |
| #define SANDBOX_WIN_SRC_RESTRICTED_TOKEN_H_ |
| |
| #include <vector> |
| |
| #include <optional> |
| #include "base/win/access_control_list.h" |
| #include "base/win/access_token.h" |
| #include "base/win/sid.h" |
| #include "base/win/windows_types.h" |
| #include "sandbox/win/src/security_level.h" |
| |
| namespace sandbox { |
| |
| // Handles the creation of a restricted token using the effective token or |
| // any token handle. |
| // Sample usage: |
| // RestrictedToken restricted_token; |
| // |
| // restricted_token.AddRestrictingSid(base::win::WellKnownSid::kUsers); |
| // auto token = restricted_token.GetRestrictedToken(); |
| // if (!token) { |
| // // handle error. |
| // } |
| // [...] |
| class RestrictedToken { |
| public: |
| RestrictedToken(); |
| |
| RestrictedToken(const RestrictedToken&) = delete; |
| RestrictedToken& operator=(const RestrictedToken&) = delete; |
| |
| ~RestrictedToken(); |
| |
| // Creates a restricted token. This creates a primary token for process |
| // creation. If the function fails an empty value is returned. |
| std::optional<base::win::AccessToken> GetRestrictedToken() const; |
| |
| // Lists all sids in the token and mark them as Deny Only except for those |
| // present in the exceptions parameter. If there is no exception needed, |
| // the caller can pass an empty list or nullptr for the exceptions |
| // parameter. |
| // |
| // Sample usage: |
| // std::vector<base::win::Sid> sid_exceptions; |
| // sid_exceptions.emplace_back(base::win::WellKnownSid::kWorld); |
| // restricted_token.AddAllSidsForDenyOnly(sid_exceptions); |
| // Note: A Sid marked for Deny Only in a token cannot be used to grant |
| // access to any resource. It can only be used to deny access. |
| void AddAllSidsForDenyOnly(const std::vector<base::win::Sid>& exceptions); |
| |
| // Adds a user or group SID for Deny Only in the restricted token. |
| // `sid` is the SID to add in the Deny Only list. |
| // |
| // Sample Usage: |
| // restricted_token.AddSidForDenyOnly(sid); |
| void AddSidForDenyOnly(const base::win::Sid& sid); |
| |
| // Adds a known SID for Deny Only in the restricted token. |
| // `known_sid` is the SID to add in the Deny Only list. |
| // Sample Usage: |
| // restricted_token.AddSidForDenyOnly(base::win::WellKnownSid::kWorld); |
| void AddSidForDenyOnly(base::win::WellKnownSid known_sid); |
| |
| // Adds the user sid of the token for Deny Only in the restricted token. |
| void AddUserSidForDenyOnly(); |
| |
| // Specify to remove all privileges in the restricted token. By default this |
| // will not remove SeChangeNotifyPrivilege, however you can specify true for |
| // `remove_traversal_privilege` to remove that privilege as well. |
| void DeleteAllPrivileges(bool remove_traversal_privilege); |
| |
| // Adds a SID to the list of restricting sids in the restricted token. |
| // `sid` is the sid to add to the list restricting sids. |
| // |
| // Sample usage: |
| // restricted_token.AddRestrictingSid(ATL::Sids::Users().GetPSID()); |
| // Note: The list of restricting is used to force Windows to perform all |
| // access checks twice. The first time using your user SID and your groups, |
| // and the second time using your list of restricting sids. The access has |
| // to be granted in both places to get access to the resource requested. |
| void AddRestrictingSid(const base::win::Sid& sid); |
| |
| // Adds a known SID to the list of restricting sids in the restricted token. |
| // `known_sid` is the sid to add to the list restricting sids. |
| |
| // Sample usage: |
| // restricted_token.AddRestrictingSid(base::win::WellKnownSid::kWorld); |
| // Note: The list of restricting is used to force Windows to perform all |
| // access checks twice. The first time using your user SID and your groups, |
| // and the second time using your list of restricting sids. The access has |
| // to be granted in both places to get access to the resource requested. |
| void AddRestrictingSid(base::win::WellKnownSid known_sid); |
| |
| // Adds the logon sid of the token in the list of restricting sids for the |
| // restricted token. |
| void AddRestrictingSidLogonSession(); |
| |
| // Adds the owner sid of the token in the list of restricting sids for the |
| // restricted token. |
| void AddRestrictingSidCurrentUser(); |
| |
| // Adds all group sids and the user sid to the restricting sids list. |
| void AddRestrictingSidAllSids(); |
| |
| // Sets the token integrity level. The integrity level cannot be higher than |
| // your current integrity level. |
| void SetIntegrityLevel(IntegrityLevel integrity_level); |
| |
| // Set a flag which indicates the created token should have a locked down |
| // default DACL when created. |
| void SetLockdownDefaultDacl(); |
| |
| // Add a SID to the default DACL. These SIDs are added regardless of the |
| // SetLockdownDefaultDacl state. |
| void AddDefaultDaclSid(const base::win::Sid& sid, |
| base::win::SecurityAccessMode access_mode, |
| ACCESS_MASK access); |
| |
| // Add a SID to the default DACL. These SIDs are added regardless of the |
| // SetLockdownDefaultDacl state. |
| void AddDefaultDaclSid(base::win::WellKnownSid known_sid, |
| base::win::SecurityAccessMode access_mode, |
| ACCESS_MASK access); |
| |
| // Creates a restricted token. This is only used for testing to change the |
| // token used to build the restricted token. |
| std::optional<base::win::AccessToken> GetRestrictedTokenForTesting( |
| base::win::AccessToken& token); |
| |
| private: |
| std::vector<base::win::Sid> BuildDenyOnlySids( |
| const base::win::AccessToken& token) const; |
| std::vector<base::win::Sid> BuildRestrictedSids( |
| const base::win::AccessToken& token) const; |
| std::optional<base::win::AccessToken> CreateRestricted( |
| const base::win::AccessToken& token) const; |
| |
| // The list of restricting sids in the restricted token. |
| std::vector<base::win::Sid> sids_to_restrict_; |
| // The list of sids to mark as Deny Only in the restricted token. |
| std::vector<base::win::Sid> sids_for_deny_only_; |
| // The list of sids to add to the default DACL of the restricted token. |
| std::vector<base::win::ExplicitAccessEntry> sids_for_default_dacl_; |
| // The token to restrict, this is only used for testing. |
| std::optional<base::win::AccessToken> effective_token_; |
| // The token integrity level RID. |
| std::optional<DWORD> integrity_rid_; |
| // Lockdown the default DACL when creating new tokens. |
| bool lockdown_default_dacl_ = false; |
| // Delete all privileges except for SeChangeNotifyPrivilege. |
| bool delete_all_privileges_ = false; |
| // Also delete SeChangeNotifyPrivilege if delete_all_privileges_ is true. |
| bool remove_traversal_privilege_ = false; |
| // Add all SIDs for deny only. |
| bool add_all_sids_for_deny_only_ = false; |
| // The list of exceptions when adding all SIDs for deny only. |
| std::vector<base::win::Sid> add_all_exceptions_; |
| // Add the user's sid to the deny only list. |
| bool add_user_sid_for_deny_only_ = false; |
| // Add the logon session SID to the restricted SID list. |
| bool add_restricting_sid_logon_session_ = false; |
| // Add the current user SID to the restricted SID list. |
| bool add_restricting_sid_current_user_ = false; |
| // Add all SIDs to the restricted SIDs. |
| bool add_restricting_sid_all_sids_ = false; |
| }; |
| |
| } // namespace sandbox |
| |
| #endif // SANDBOX_WIN_SRC_RESTRICTED_TOKEN_H_ |