1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 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 SANDBOX_SRC_RESTRICTED_TOKEN_H_ 6 #define SANDBOX_SRC_RESTRICTED_TOKEN_H_ 7 8 #include <windows.h> 9 #include <vector> 10 11 #include "base/basictypes.h" 12 #include "sandbox/win/src/restricted_token_utils.h" 13 #include "sandbox/win/src/security_level.h" 14 #include "sandbox/win/src/sid.h" 15 16 // Flags present in the Group SID list. These 2 flags are new in Windows Vista 17 #ifndef SE_GROUP_INTEGRITY 18 #define SE_GROUP_INTEGRITY (0x00000020L) 19 #endif 20 #ifndef SE_GROUP_INTEGRITY_ENABLED 21 #define SE_GROUP_INTEGRITY_ENABLED (0x00000040L) 22 #endif 23 24 namespace sandbox { 25 26 // Handles the creation of a restricted token using the effective token or 27 // any token handle. 28 // Sample usage: 29 // RestrictedToken restricted_token; 30 // unsigned err_code = restricted_token.Init(NULL); // Use the current 31 // // effective token 32 // if (ERROR_SUCCESS != err_code) { 33 // // handle error. 34 // } 35 // 36 // restricted_token.AddRestrictingSid(ATL::Sids::Users().GetPSID()); 37 // HANDLE token_handle; 38 // err_code = restricted_token.GetRestrictedTokenHandle(&token_handle); 39 // if (ERROR_SUCCESS != err_code) { 40 // // handle error. 41 // } 42 // [...] 43 // CloseHandle(token_handle); 44 class RestrictedToken { 45 public: 46 // Init() has to be called before calling any other method in the class. 47 RestrictedToken() 48 : init_(false), effective_token_(NULL), 49 integrity_level_(INTEGRITY_LEVEL_LAST) { } 50 51 ~RestrictedToken() { 52 if (effective_token_) 53 CloseHandle(effective_token_); 54 } 55 56 // Initializes the RestrictedToken object with effective_token. 57 // If effective_token is NULL, it initializes the RestrictedToken object with 58 // the effective token of the current process. 59 unsigned Init(HANDLE effective_token); 60 61 // Creates a restricted token and returns its handle using the token_handle 62 // output parameter. This handle has to be closed by the caller. 63 // If the function succeeds, the return value is ERROR_SUCCESS. If the 64 // function fails, the return value is the win32 error code corresponding to 65 // the error. 66 unsigned GetRestrictedTokenHandle(HANDLE *token_handle) const; 67 68 // Creates a restricted token and uses this new token to create a new token 69 // for impersonation. Returns the handle of this impersonation token using 70 // the token_handle output parameter. This handle has to be closed by 71 // the caller. 72 // 73 // If the function succeeds, the return value is ERROR_SUCCESS. If the 74 // function fails, the return value is the win32 error code corresponding to 75 // the error. 76 // 77 // The sample usage is the same as the GetRestrictedTokenHandle function. 78 unsigned GetRestrictedTokenHandleForImpersonation(HANDLE *token_handle) const; 79 80 // Lists all sids in the token and mark them as Deny Only except for those 81 // present in the exceptions parameter. If there is no exception needed, 82 // the caller can pass an empty list or NULL for the exceptions 83 // parameter. 84 // 85 // If the function succeeds, the return value is ERROR_SUCCESS. If the 86 // function fails, the return value is the win32 error code corresponding to 87 // the error. 88 // 89 // Sample usage: 90 // std::vector<Sid> sid_exceptions; 91 // sid_exceptions.push_back(ATL::Sids::Users().GetPSID()); 92 // sid_exceptions.push_back(ATL::Sids::World().GetPSID()); 93 // restricted_token.AddAllSidsForDenyOnly(&sid_exceptions); 94 // Note: A Sid marked for Deny Only in a token cannot be used to grant 95 // access to any resource. It can only be used to deny access. 96 unsigned AddAllSidsForDenyOnly(std::vector<Sid> *exceptions); 97 98 // Adds a user or group SID for Deny Only in the restricted token. 99 // Parameter: sid is the SID to add in the Deny Only list. 100 // The return value is always ERROR_SUCCESS. 101 // 102 // Sample Usage: 103 // restricted_token.AddSidForDenyOnly(ATL::Sids::Admins().GetPSID()); 104 unsigned AddSidForDenyOnly(const Sid &sid); 105 106 // Adds the user sid of the token for Deny Only in the restricted token. 107 // If the function succeeds, the return value is ERROR_SUCCESS. If the 108 // function fails, the return value is the win32 error code corresponding to 109 // the error. 110 unsigned AddUserSidForDenyOnly(); 111 112 // Lists all privileges in the token and add them to the list of privileges 113 // to remove except for those present in the exceptions parameter. If 114 // there is no exception needed, the caller can pass an empty list or NULL 115 // for the exceptions parameter. 116 // 117 // If the function succeeds, the return value is ERROR_SUCCESS. If the 118 // function fails, the return value is the win32 error code corresponding to 119 // the error. 120 // 121 // Sample usage: 122 // std::vector<std::wstring> privilege_exceptions; 123 // privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME); 124 // restricted_token.DeleteAllPrivileges(&privilege_exceptions); 125 unsigned DeleteAllPrivileges( 126 const std::vector<std::wstring> *exceptions); 127 128 // Adds a privilege to the list of privileges to remove in the restricted 129 // token. 130 // Parameter: privilege is the privilege name to remove. This is the string 131 // representing the privilege. (e.g. "SeChangeNotifyPrivilege"). 132 // If the function succeeds, the return value is ERROR_SUCCESS. If the 133 // function fails, the return value is the win32 error code corresponding to 134 // the error. 135 // 136 // Sample usage: 137 // restricted_token.DeletePrivilege(SE_LOAD_DRIVER_NAME); 138 unsigned DeletePrivilege(const wchar_t *privilege); 139 140 // Adds a SID to the list of restricting sids in the restricted token. 141 // Parameter: sid is the sid to add to the list restricting sids. 142 // The return value is always ERROR_SUCCESS. 143 // 144 // Sample usage: 145 // restricted_token.AddRestrictingSid(ATL::Sids::Users().GetPSID()); 146 // Note: The list of restricting is used to force Windows to perform all 147 // access checks twice. The first time using your user SID and your groups, 148 // and the second time using your list of restricting sids. The access has 149 // to be granted in both places to get access to the resource requested. 150 unsigned AddRestrictingSid(const Sid &sid); 151 152 // Adds the logon sid of the token in the list of restricting sids for the 153 // restricted token. 154 // 155 // If the function succeeds, the return value is ERROR_SUCCESS. If the 156 // function fails, the return value is the win32 error code corresponding to 157 // the error. 158 unsigned AddRestrictingSidLogonSession(); 159 160 // Adds the owner sid of the token in the list of restricting sids for the 161 // restricted token. 162 // 163 // If the function succeeds, the return value is ERROR_SUCCESS. If the 164 // function fails, the return value is the win32 error code corresponding to 165 // the error. 166 unsigned AddRestrictingSidCurrentUser(); 167 168 // Adds all group sids and the user sid to the restricting sids list. 169 // 170 // If the function succeeds, the return value is ERROR_SUCCESS. If the 171 // function fails, the return value is the win32 error code corresponding to 172 // the error. 173 unsigned AddRestrictingSidAllSids(); 174 175 // Sets the token integrity level. This is only valid on Vista. The integrity 176 // level cannot be higher than your current integrity level. 177 unsigned SetIntegrityLevel(IntegrityLevel integrity_level); 178 179 private: 180 // The list of restricting sids in the restricted token. 181 std::vector<Sid> sids_to_restrict_; 182 // The list of privileges to remove in the restricted token. 183 std::vector<LUID> privileges_to_disable_; 184 // The list of sids to mark as Deny Only in the restricted token. 185 std::vector<Sid> sids_for_deny_only_; 186 // The token to restrict. Can only be set in a constructor. 187 HANDLE effective_token_; 188 // The token integrity level. Only valid on Vista. 189 IntegrityLevel integrity_level_; 190 // Tells if the object is initialized or not (if Init() has been called) 191 bool init_; 192 193 DISALLOW_COPY_AND_ASSIGN(RestrictedToken); 194 }; 195 196 } // namespace sandbox 197 198 #endif // SANDBOX_SRC_RESTRICTED_TOKEN_H_ 199