| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "sandbox/win/src/restricted_token.h" | 5 #include "sandbox/win/src/restricted_token.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "sandbox/win/src/acl.h" | 10 #include "sandbox/win/src/acl.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 if (!::OpenProcessToken(::GetCurrentProcess(), | 46 if (!::OpenProcessToken(::GetCurrentProcess(), |
| 47 TOKEN_ALL_ACCESS, | 47 TOKEN_ALL_ACCESS, |
| 48 &effective_token_)) | 48 &effective_token_)) |
| 49 return ::GetLastError(); | 49 return ::GetLastError(); |
| 50 } | 50 } |
| 51 | 51 |
| 52 init_ = true; | 52 init_ = true; |
| 53 return ERROR_SUCCESS; | 53 return ERROR_SUCCESS; |
| 54 } | 54 } |
| 55 | 55 |
| 56 unsigned RestrictedToken::GetRestrictedTokenHandle(HANDLE *token_handle) const { | 56 unsigned RestrictedToken::GetRestrictedToken( |
| 57 base::win::ScopedHandle* token) const { |
| 57 DCHECK(init_); | 58 DCHECK(init_); |
| 58 if (!init_) | 59 if (!init_) |
| 59 return ERROR_NO_TOKEN; | 60 return ERROR_NO_TOKEN; |
| 60 | 61 |
| 61 size_t deny_size = sids_for_deny_only_.size(); | 62 size_t deny_size = sids_for_deny_only_.size(); |
| 62 size_t restrict_size = sids_to_restrict_.size(); | 63 size_t restrict_size = sids_to_restrict_.size(); |
| 63 size_t privileges_size = privileges_to_disable_.size(); | 64 size_t privileges_size = privileges_to_disable_.size(); |
| 64 | 65 |
| 65 SID_AND_ATTRIBUTES *deny_only_array = NULL; | 66 SID_AND_ATTRIBUTES *deny_only_array = NULL; |
| 66 if (deny_size) { | 67 if (deny_size) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 88 if (privileges_size) { | 89 if (privileges_size) { |
| 89 privileges_to_disable_array = new LUID_AND_ATTRIBUTES[privileges_size]; | 90 privileges_to_disable_array = new LUID_AND_ATTRIBUTES[privileges_size]; |
| 90 | 91 |
| 91 for (unsigned int i = 0; i < privileges_size; ++i) { | 92 for (unsigned int i = 0; i < privileges_size; ++i) { |
| 92 privileges_to_disable_array[i].Attributes = 0; | 93 privileges_to_disable_array[i].Attributes = 0; |
| 93 privileges_to_disable_array[i].Luid = privileges_to_disable_[i]; | 94 privileges_to_disable_array[i].Luid = privileges_to_disable_[i]; |
| 94 } | 95 } |
| 95 } | 96 } |
| 96 | 97 |
| 97 BOOL result = TRUE; | 98 BOOL result = TRUE; |
| 98 HANDLE new_token = NULL; | 99 HANDLE new_token_handle = NULL; |
| 99 // The SANDBOX_INERT flag did nothing in XP and it was just a way to tell | 100 // The SANDBOX_INERT flag did nothing in XP and it was just a way to tell |
| 100 // if a token has ben restricted given the limiations of IsTokenRestricted() | 101 // if a token has ben restricted given the limiations of IsTokenRestricted() |
| 101 // but it appears that in Windows 7 it hints the AppLocker subsystem to | 102 // but it appears that in Windows 7 it hints the AppLocker subsystem to |
| 102 // leave us alone. | 103 // leave us alone. |
| 103 if (deny_size || restrict_size || privileges_size) { | 104 if (deny_size || restrict_size || privileges_size) { |
| 104 result = ::CreateRestrictedToken(effective_token_, | 105 result = ::CreateRestrictedToken(effective_token_, |
| 105 SANDBOX_INERT, | 106 SANDBOX_INERT, |
| 106 static_cast<DWORD>(deny_size), | 107 static_cast<DWORD>(deny_size), |
| 107 deny_only_array, | 108 deny_only_array, |
| 108 static_cast<DWORD>(privileges_size), | 109 static_cast<DWORD>(privileges_size), |
| 109 privileges_to_disable_array, | 110 privileges_to_disable_array, |
| 110 static_cast<DWORD>(restrict_size), | 111 static_cast<DWORD>(restrict_size), |
| 111 sids_to_restrict_array, | 112 sids_to_restrict_array, |
| 112 &new_token); | 113 &new_token_handle); |
| 113 } else { | 114 } else { |
| 114 // Duplicate the token even if it's not modified at this point | 115 // Duplicate the token even if it's not modified at this point |
| 115 // because any subsequent changes to this token would also affect the | 116 // because any subsequent changes to this token would also affect the |
| 116 // current process. | 117 // current process. |
| 117 result = ::DuplicateTokenEx(effective_token_, TOKEN_ALL_ACCESS, NULL, | 118 result = ::DuplicateTokenEx(effective_token_, TOKEN_ALL_ACCESS, NULL, |
| 118 SecurityIdentification, TokenPrimary, | 119 SecurityIdentification, TokenPrimary, |
| 119 &new_token); | 120 &new_token_handle); |
| 120 } | 121 } |
| 121 | 122 |
| 122 if (deny_only_array) | 123 if (deny_only_array) |
| 123 delete[] deny_only_array; | 124 delete[] deny_only_array; |
| 124 | 125 |
| 125 if (sids_to_restrict_array) | 126 if (sids_to_restrict_array) |
| 126 delete[] sids_to_restrict_array; | 127 delete[] sids_to_restrict_array; |
| 127 | 128 |
| 128 if (privileges_to_disable_array) | 129 if (privileges_to_disable_array) |
| 129 delete[] privileges_to_disable_array; | 130 delete[] privileges_to_disable_array; |
| 130 | 131 |
| 131 if (!result) | 132 if (!result) |
| 132 return ::GetLastError(); | 133 return ::GetLastError(); |
| 133 | 134 |
| 135 base::win::ScopedHandle new_token(new_token_handle); |
| 136 |
| 134 // Modify the default dacl on the token to contain Restricted and the user. | 137 // Modify the default dacl on the token to contain Restricted and the user. |
| 135 if (!AddSidToDefaultDacl(new_token, WinRestrictedCodeSid, GENERIC_ALL)) | 138 if (!AddSidToDefaultDacl(new_token.Get(), WinRestrictedCodeSid, GENERIC_ALL)) |
| 136 return ::GetLastError(); | 139 return ::GetLastError(); |
| 137 | 140 |
| 138 if (!AddUserSidToDefaultDacl(new_token, GENERIC_ALL)) | 141 if (!AddUserSidToDefaultDacl(new_token.Get(), GENERIC_ALL)) |
| 139 return ::GetLastError(); | 142 return ::GetLastError(); |
| 140 | 143 |
| 141 DWORD error = SetTokenIntegrityLevel(new_token, integrity_level_); | 144 DWORD error = SetTokenIntegrityLevel(new_token.Get(), integrity_level_); |
| 142 if (ERROR_SUCCESS != error) | 145 if (ERROR_SUCCESS != error) |
| 143 return error; | 146 return error; |
| 144 | 147 |
| 145 BOOL status = ::DuplicateHandle(::GetCurrentProcess(), | 148 HANDLE token_handle; |
| 146 new_token, | 149 if (!::DuplicateHandle(::GetCurrentProcess(), new_token.Get(), |
| 147 ::GetCurrentProcess(), | 150 ::GetCurrentProcess(), &token_handle, |
| 148 token_handle, | 151 TOKEN_ALL_ACCESS, FALSE, // Don't inherit. |
| 149 TOKEN_ALL_ACCESS, | 152 0)) { |
| 150 FALSE, // Don't inherit. | 153 return ::GetLastError(); |
| 151 0); | 154 } |
| 152 | 155 |
| 153 if (new_token != effective_token_) | 156 token->Set(token_handle); |
| 154 ::CloseHandle(new_token); | |
| 155 | |
| 156 if (!status) | |
| 157 return ::GetLastError(); | |
| 158 | |
| 159 return ERROR_SUCCESS; | 157 return ERROR_SUCCESS; |
| 160 } | 158 } |
| 161 | 159 |
| 162 unsigned RestrictedToken::GetRestrictedTokenHandleForImpersonation( | 160 unsigned RestrictedToken::GetRestrictedTokenForImpersonation( |
| 163 HANDLE *token_handle) const { | 161 base::win::ScopedHandle* token) const { |
| 164 DCHECK(init_); | 162 DCHECK(init_); |
| 165 if (!init_) | 163 if (!init_) |
| 166 return ERROR_NO_TOKEN; | 164 return ERROR_NO_TOKEN; |
| 167 | 165 |
| 168 HANDLE restricted_token_handle; | 166 base::win::ScopedHandle restricted_token; |
| 169 unsigned err_code = GetRestrictedTokenHandle(&restricted_token_handle); | 167 unsigned err_code = GetRestrictedToken(&restricted_token); |
| 170 if (ERROR_SUCCESS != err_code) | 168 if (ERROR_SUCCESS != err_code) |
| 171 return err_code; | 169 return err_code; |
| 172 | 170 |
| 173 HANDLE impersonation_token; | 171 HANDLE impersonation_token_handle; |
| 174 if (!::DuplicateToken(restricted_token_handle, | 172 if (!::DuplicateToken(restricted_token.Get(), |
| 175 SecurityImpersonation, | 173 SecurityImpersonation, |
| 176 &impersonation_token)) { | 174 &impersonation_token_handle)) { |
| 177 ::CloseHandle(restricted_token_handle); | 175 return ::GetLastError(); |
| 176 } |
| 177 base::win::ScopedHandle impersonation_token(impersonation_token_handle); |
| 178 |
| 179 HANDLE token_handle; |
| 180 if (!::DuplicateHandle(::GetCurrentProcess(), impersonation_token.Get(), |
| 181 ::GetCurrentProcess(), &token_handle, |
| 182 TOKEN_ALL_ACCESS, FALSE, // Don't inherit. |
| 183 0)) { |
| 178 return ::GetLastError(); | 184 return ::GetLastError(); |
| 179 } | 185 } |
| 180 | 186 |
| 181 ::CloseHandle(restricted_token_handle); | 187 token->Set(token_handle); |
| 182 | |
| 183 BOOL status = ::DuplicateHandle(::GetCurrentProcess(), | |
| 184 impersonation_token, | |
| 185 ::GetCurrentProcess(), | |
| 186 token_handle, | |
| 187 TOKEN_ALL_ACCESS, | |
| 188 FALSE, // Don't inherit. | |
| 189 0); | |
| 190 | |
| 191 ::CloseHandle(impersonation_token); | |
| 192 | |
| 193 if (!status) | |
| 194 return ::GetLastError(); | |
| 195 | |
| 196 return ERROR_SUCCESS; | 188 return ERROR_SUCCESS; |
| 197 } | 189 } |
| 198 | 190 |
| 199 unsigned RestrictedToken::AddAllSidsForDenyOnly(std::vector<Sid> *exceptions) { | 191 unsigned RestrictedToken::AddAllSidsForDenyOnly(std::vector<Sid> *exceptions) { |
| 200 DCHECK(init_); | 192 DCHECK(init_); |
| 201 if (!init_) | 193 if (!init_) |
| 202 return ERROR_NO_TOKEN; | 194 return ERROR_NO_TOKEN; |
| 203 | 195 |
| 204 TOKEN_GROUPS *token_groups = NULL; | 196 TOKEN_GROUPS *token_groups = NULL; |
| 205 DWORD size = 0; | 197 DWORD size = 0; |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 | 464 |
| 473 return ERROR_SUCCESS; | 465 return ERROR_SUCCESS; |
| 474 } | 466 } |
| 475 | 467 |
| 476 unsigned RestrictedToken::SetIntegrityLevel(IntegrityLevel integrity_level) { | 468 unsigned RestrictedToken::SetIntegrityLevel(IntegrityLevel integrity_level) { |
| 477 integrity_level_ = integrity_level; | 469 integrity_level_ = integrity_level; |
| 478 return ERROR_SUCCESS; | 470 return ERROR_SUCCESS; |
| 479 } | 471 } |
| 480 | 472 |
| 481 } // namespace sandbox | 473 } // namespace sandbox |
| OLD | NEW |