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 |