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