| 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 "remoting/host/win/launch_process_with_token.h" | 5 #include "remoting/host/win/launch_process_with_token.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <winternl.h> | 8 #include <winternl.h> |
| 9 | 9 |
| 10 #include <limits> | 10 #include <limits> |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 bool CopyProcessToken(DWORD desired_access, ScopedHandle* token_out) { | 125 bool CopyProcessToken(DWORD desired_access, ScopedHandle* token_out) { |
| 126 HANDLE temp_handle; | 126 HANDLE temp_handle; |
| 127 if (!OpenProcessToken(GetCurrentProcess(), | 127 if (!OpenProcessToken(GetCurrentProcess(), |
| 128 TOKEN_DUPLICATE | desired_access, | 128 TOKEN_DUPLICATE | desired_access, |
| 129 &temp_handle)) { | 129 &temp_handle)) { |
| 130 PLOG(ERROR) << "Failed to open process token"; | 130 PLOG(ERROR) << "Failed to open process token"; |
| 131 return false; | 131 return false; |
| 132 } | 132 } |
| 133 ScopedHandle process_token(temp_handle); | 133 ScopedHandle process_token(temp_handle); |
| 134 | 134 |
| 135 if (!DuplicateTokenEx(process_token, | 135 if (!DuplicateTokenEx(process_token.Get(), |
| 136 desired_access, | 136 desired_access, |
| 137 NULL, | 137 NULL, |
| 138 SecurityImpersonation, | 138 SecurityImpersonation, |
| 139 TokenPrimary, | 139 TokenPrimary, |
| 140 &temp_handle)) { | 140 &temp_handle)) { |
| 141 PLOG(ERROR) << "Failed to duplicate the process token"; | 141 PLOG(ERROR) << "Failed to duplicate the process token"; |
| 142 return false; | 142 return false; |
| 143 } | 143 } |
| 144 | 144 |
| 145 token_out->Set(temp_handle); | 145 token_out->Set(temp_handle); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 158 // Get the LUID for the SE_TCB_NAME privilege. | 158 // Get the LUID for the SE_TCB_NAME privilege. |
| 159 TOKEN_PRIVILEGES state; | 159 TOKEN_PRIVILEGES state; |
| 160 state.PrivilegeCount = 1; | 160 state.PrivilegeCount = 1; |
| 161 state.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; | 161 state.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; |
| 162 if (!LookupPrivilegeValue(NULL, SE_TCB_NAME, &state.Privileges[0].Luid)) { | 162 if (!LookupPrivilegeValue(NULL, SE_TCB_NAME, &state.Privileges[0].Luid)) { |
| 163 PLOG(ERROR) << "Failed to lookup the LUID for the SE_TCB_NAME privilege"; | 163 PLOG(ERROR) << "Failed to lookup the LUID for the SE_TCB_NAME privilege"; |
| 164 return false; | 164 return false; |
| 165 } | 165 } |
| 166 | 166 |
| 167 // Enable the SE_TCB_NAME privilege. | 167 // Enable the SE_TCB_NAME privilege. |
| 168 if (!AdjustTokenPrivileges(privileged_token, FALSE, &state, 0, NULL, 0)) { | 168 if (!AdjustTokenPrivileges(privileged_token.Get(), FALSE, &state, 0, NULL, |
| 169 0)) { |
| 169 PLOG(ERROR) << "Failed to enable SE_TCB_NAME privilege in a token"; | 170 PLOG(ERROR) << "Failed to enable SE_TCB_NAME privilege in a token"; |
| 170 return false; | 171 return false; |
| 171 } | 172 } |
| 172 | 173 |
| 173 *token_out = privileged_token.Pass(); | 174 *token_out = privileged_token.Pass(); |
| 174 return true; | 175 return true; |
| 175 } | 176 } |
| 176 | 177 |
| 177 // Fills the process and thread handles in the passed |process_information| | 178 // Fills the process and thread handles in the passed |process_information| |
| 178 // structure and resume the process if the caller didn't want to suspend it. | 179 // structure and resume the process if the caller didn't want to suspend it. |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 const base::CommandLine::StringType& command_line, | 374 const base::CommandLine::StringType& command_line, |
| 374 DWORD creation_flags, | 375 DWORD creation_flags, |
| 375 const base::char16* desktop_name, | 376 const base::char16* desktop_name, |
| 376 PROCESS_INFORMATION* process_information_out) { | 377 PROCESS_INFORMATION* process_information_out) { |
| 377 DCHECK_LT(base::win::GetVersion(), base::win::VERSION_VISTA); | 378 DCHECK_LT(base::win::GetVersion(), base::win::VERSION_VISTA); |
| 378 | 379 |
| 379 base::win::ScopedHandle pipe; | 380 base::win::ScopedHandle pipe; |
| 380 if (!ConnectToExecutionServer(session_id, &pipe)) | 381 if (!ConnectToExecutionServer(session_id, &pipe)) |
| 381 return false; | 382 return false; |
| 382 | 383 |
| 383 if (!SendCreateProcessRequest(pipe, application_name, command_line, | 384 if (!SendCreateProcessRequest(pipe.Get(), application_name, command_line, |
| 384 creation_flags, desktop_name)) { | 385 creation_flags, desktop_name)) { |
| 385 return false; | 386 return false; |
| 386 } | 387 } |
| 387 | 388 |
| 388 PROCESS_INFORMATION process_information; | 389 PROCESS_INFORMATION process_information; |
| 389 if (!ReceiveCreateProcessResponse(pipe, &process_information)) | 390 if (!ReceiveCreateProcessResponse(pipe.Get(), &process_information)) |
| 390 return false; | 391 return false; |
| 391 | 392 |
| 392 if (!ProcessCreateProcessResponse(creation_flags, &process_information)) { | 393 if (!ProcessCreateProcessResponse(creation_flags, &process_information)) { |
| 393 CloseHandlesAndTerminateProcess(&process_information); | 394 CloseHandlesAndTerminateProcess(&process_information); |
| 394 return false; | 395 return false; |
| 395 } | 396 } |
| 396 | 397 |
| 397 *process_information_out = process_information; | 398 *process_information_out = process_information; |
| 398 return true; | 399 return true; |
| 399 } | 400 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 414 if (!CopyProcessToken(desired_access, &session_token)) { | 415 if (!CopyProcessToken(desired_access, &session_token)) { |
| 415 return false; | 416 return false; |
| 416 } | 417 } |
| 417 | 418 |
| 418 // Temporarily enable the SE_TCB_NAME privilege as it is required by | 419 // Temporarily enable the SE_TCB_NAME privilege as it is required by |
| 419 // SetTokenInformation(TokenSessionId). | 420 // SetTokenInformation(TokenSessionId). |
| 420 ScopedHandle privileged_token; | 421 ScopedHandle privileged_token; |
| 421 if (!CreatePrivilegedToken(&privileged_token)) { | 422 if (!CreatePrivilegedToken(&privileged_token)) { |
| 422 return false; | 423 return false; |
| 423 } | 424 } |
| 424 if (!ImpersonateLoggedOnUser(privileged_token)) { | 425 if (!ImpersonateLoggedOnUser(privileged_token.Get())) { |
| 425 PLOG(ERROR) << "Failed to impersonate the privileged token"; | 426 PLOG(ERROR) << "Failed to impersonate the privileged token"; |
| 426 return false; | 427 return false; |
| 427 } | 428 } |
| 428 | 429 |
| 429 // Change the session ID of the token. | 430 // Change the session ID of the token. |
| 430 DWORD new_session_id = session_id; | 431 DWORD new_session_id = session_id; |
| 431 if (!SetTokenInformation(session_token, | 432 if (!SetTokenInformation(session_token.Get(), |
| 432 TokenSessionId, | 433 TokenSessionId, |
| 433 &new_session_id, | 434 &new_session_id, |
| 434 sizeof(new_session_id))) { | 435 sizeof(new_session_id))) { |
| 435 PLOG(ERROR) << "Failed to change session ID of a token"; | 436 PLOG(ERROR) << "Failed to change session ID of a token"; |
| 436 | 437 |
| 437 // Revert to the default token. | 438 // Revert to the default token. |
| 438 CHECK(RevertToSelf()); | 439 CHECK(RevertToSelf()); |
| 439 return false; | 440 return false; |
| 440 } | 441 } |
| 441 | 442 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 | 515 |
| 515 base::win::ScopedProcessInformation process_info(temp_process_info); | 516 base::win::ScopedProcessInformation process_info(temp_process_info); |
| 516 | 517 |
| 517 CHECK(process_info.IsValid()); | 518 CHECK(process_info.IsValid()); |
| 518 process_out->Set(process_info.TakeProcessHandle()); | 519 process_out->Set(process_info.TakeProcessHandle()); |
| 519 thread_out->Set(process_info.TakeThreadHandle()); | 520 thread_out->Set(process_info.TakeThreadHandle()); |
| 520 return true; | 521 return true; |
| 521 } | 522 } |
| 522 | 523 |
| 523 } // namespace remoting | 524 } // namespace remoting |
| OLD | NEW |