michael@0: // Copyright (c) 2010 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #ifndef SANDBOX_SRC_RESTRICTED_TOKEN_H_ michael@0: #define SANDBOX_SRC_RESTRICTED_TOKEN_H_ michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include "base/basictypes.h" michael@0: #include "sandbox/win/src/restricted_token_utils.h" michael@0: #include "sandbox/win/src/security_level.h" michael@0: #include "sandbox/win/src/sid.h" michael@0: michael@0: // Flags present in the Group SID list. These 2 flags are new in Windows Vista michael@0: #ifndef SE_GROUP_INTEGRITY michael@0: #define SE_GROUP_INTEGRITY (0x00000020L) michael@0: #endif michael@0: #ifndef SE_GROUP_INTEGRITY_ENABLED michael@0: #define SE_GROUP_INTEGRITY_ENABLED (0x00000040L) michael@0: #endif michael@0: michael@0: namespace sandbox { michael@0: michael@0: // Handles the creation of a restricted token using the effective token or michael@0: // any token handle. michael@0: // Sample usage: michael@0: // RestrictedToken restricted_token; michael@0: // unsigned err_code = restricted_token.Init(NULL); // Use the current michael@0: // // effective token michael@0: // if (ERROR_SUCCESS != err_code) { michael@0: // // handle error. michael@0: // } michael@0: // michael@0: // restricted_token.AddRestrictingSid(ATL::Sids::Users().GetPSID()); michael@0: // HANDLE token_handle; michael@0: // err_code = restricted_token.GetRestrictedTokenHandle(&token_handle); michael@0: // if (ERROR_SUCCESS != err_code) { michael@0: // // handle error. michael@0: // } michael@0: // [...] michael@0: // CloseHandle(token_handle); michael@0: class RestrictedToken { michael@0: public: michael@0: // Init() has to be called before calling any other method in the class. michael@0: RestrictedToken() michael@0: : init_(false), effective_token_(NULL), michael@0: integrity_level_(INTEGRITY_LEVEL_LAST) { } michael@0: michael@0: ~RestrictedToken() { michael@0: if (effective_token_) michael@0: CloseHandle(effective_token_); michael@0: } michael@0: michael@0: // Initializes the RestrictedToken object with effective_token. michael@0: // If effective_token is NULL, it initializes the RestrictedToken object with michael@0: // the effective token of the current process. michael@0: unsigned Init(HANDLE effective_token); michael@0: michael@0: // Creates a restricted token and returns its handle using the token_handle michael@0: // output parameter. This handle has to be closed by the caller. michael@0: // If the function succeeds, the return value is ERROR_SUCCESS. If the michael@0: // function fails, the return value is the win32 error code corresponding to michael@0: // the error. michael@0: unsigned GetRestrictedTokenHandle(HANDLE *token_handle) const; michael@0: michael@0: // Creates a restricted token and uses this new token to create a new token michael@0: // for impersonation. Returns the handle of this impersonation token using michael@0: // the token_handle output parameter. This handle has to be closed by michael@0: // the caller. michael@0: // michael@0: // If the function succeeds, the return value is ERROR_SUCCESS. If the michael@0: // function fails, the return value is the win32 error code corresponding to michael@0: // the error. michael@0: // michael@0: // The sample usage is the same as the GetRestrictedTokenHandle function. michael@0: unsigned GetRestrictedTokenHandleForImpersonation(HANDLE *token_handle) const; michael@0: michael@0: // Lists all sids in the token and mark them as Deny Only except for those michael@0: // present in the exceptions parameter. If there is no exception needed, michael@0: // the caller can pass an empty list or NULL for the exceptions michael@0: // parameter. michael@0: // michael@0: // If the function succeeds, the return value is ERROR_SUCCESS. If the michael@0: // function fails, the return value is the win32 error code corresponding to michael@0: // the error. michael@0: // michael@0: // Sample usage: michael@0: // std::vector sid_exceptions; michael@0: // sid_exceptions.push_back(ATL::Sids::Users().GetPSID()); michael@0: // sid_exceptions.push_back(ATL::Sids::World().GetPSID()); michael@0: // restricted_token.AddAllSidsForDenyOnly(&sid_exceptions); michael@0: // Note: A Sid marked for Deny Only in a token cannot be used to grant michael@0: // access to any resource. It can only be used to deny access. michael@0: unsigned AddAllSidsForDenyOnly(std::vector *exceptions); michael@0: michael@0: // Adds a user or group SID for Deny Only in the restricted token. michael@0: // Parameter: sid is the SID to add in the Deny Only list. michael@0: // The return value is always ERROR_SUCCESS. michael@0: // michael@0: // Sample Usage: michael@0: // restricted_token.AddSidForDenyOnly(ATL::Sids::Admins().GetPSID()); michael@0: unsigned AddSidForDenyOnly(const Sid &sid); michael@0: michael@0: // Adds the user sid of the token for Deny Only in the restricted token. michael@0: // If the function succeeds, the return value is ERROR_SUCCESS. If the michael@0: // function fails, the return value is the win32 error code corresponding to michael@0: // the error. michael@0: unsigned AddUserSidForDenyOnly(); michael@0: michael@0: // Lists all privileges in the token and add them to the list of privileges michael@0: // to remove except for those present in the exceptions parameter. If michael@0: // there is no exception needed, the caller can pass an empty list or NULL michael@0: // for the exceptions parameter. michael@0: // michael@0: // If the function succeeds, the return value is ERROR_SUCCESS. If the michael@0: // function fails, the return value is the win32 error code corresponding to michael@0: // the error. michael@0: // michael@0: // Sample usage: michael@0: // std::vector privilege_exceptions; michael@0: // privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME); michael@0: // restricted_token.DeleteAllPrivileges(&privilege_exceptions); michael@0: unsigned DeleteAllPrivileges( michael@0: const std::vector *exceptions); michael@0: michael@0: // Adds a privilege to the list of privileges to remove in the restricted michael@0: // token. michael@0: // Parameter: privilege is the privilege name to remove. This is the string michael@0: // representing the privilege. (e.g. "SeChangeNotifyPrivilege"). michael@0: // If the function succeeds, the return value is ERROR_SUCCESS. If the michael@0: // function fails, the return value is the win32 error code corresponding to michael@0: // the error. michael@0: // michael@0: // Sample usage: michael@0: // restricted_token.DeletePrivilege(SE_LOAD_DRIVER_NAME); michael@0: unsigned DeletePrivilege(const wchar_t *privilege); michael@0: michael@0: // Adds a SID to the list of restricting sids in the restricted token. michael@0: // Parameter: sid is the sid to add to the list restricting sids. michael@0: // The return value is always ERROR_SUCCESS. michael@0: // michael@0: // Sample usage: michael@0: // restricted_token.AddRestrictingSid(ATL::Sids::Users().GetPSID()); michael@0: // Note: The list of restricting is used to force Windows to perform all michael@0: // access checks twice. The first time using your user SID and your groups, michael@0: // and the second time using your list of restricting sids. The access has michael@0: // to be granted in both places to get access to the resource requested. michael@0: unsigned AddRestrictingSid(const Sid &sid); michael@0: michael@0: // Adds the logon sid of the token in the list of restricting sids for the michael@0: // restricted token. michael@0: // michael@0: // If the function succeeds, the return value is ERROR_SUCCESS. If the michael@0: // function fails, the return value is the win32 error code corresponding to michael@0: // the error. michael@0: unsigned AddRestrictingSidLogonSession(); michael@0: michael@0: // Adds the owner sid of the token in the list of restricting sids for the michael@0: // restricted token. michael@0: // michael@0: // If the function succeeds, the return value is ERROR_SUCCESS. If the michael@0: // function fails, the return value is the win32 error code corresponding to michael@0: // the error. michael@0: unsigned AddRestrictingSidCurrentUser(); michael@0: michael@0: // Adds all group sids and the user sid to the restricting sids list. michael@0: // michael@0: // If the function succeeds, the return value is ERROR_SUCCESS. If the michael@0: // function fails, the return value is the win32 error code corresponding to michael@0: // the error. michael@0: unsigned AddRestrictingSidAllSids(); michael@0: michael@0: // Sets the token integrity level. This is only valid on Vista. The integrity michael@0: // level cannot be higher than your current integrity level. michael@0: unsigned SetIntegrityLevel(IntegrityLevel integrity_level); michael@0: michael@0: private: michael@0: // The list of restricting sids in the restricted token. michael@0: std::vector sids_to_restrict_; michael@0: // The list of privileges to remove in the restricted token. michael@0: std::vector privileges_to_disable_; michael@0: // The list of sids to mark as Deny Only in the restricted token. michael@0: std::vector sids_for_deny_only_; michael@0: // The token to restrict. Can only be set in a constructor. michael@0: HANDLE effective_token_; michael@0: // The token integrity level. Only valid on Vista. michael@0: IntegrityLevel integrity_level_; michael@0: // Tells if the object is initialized or not (if Init() has been called) michael@0: bool init_; michael@0: michael@0: DISALLOW_COPY_AND_ASSIGN(RestrictedToken); michael@0: }; michael@0: michael@0: } // namespace sandbox michael@0: michael@0: #endif // SANDBOX_SRC_RESTRICTED_TOKEN_H_