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