Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Side by Side Diff: remoting/host/win/launch_process_with_token.cc

Issue 92173002: Merge 237541 "Revert of https://codereview.chromium.org/71013004/" (Closed) Base URL: svn://svn.chromium.org/chrome/branches/1721/src/
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 return false; 115 return false;
116 } 116 }
117 117
118 *pipe_out = pipe.Pass(); 118 *pipe_out = pipe.Pass();
119 return true; 119 return true;
120 } 120 }
121 121
122 // Copies the process token making it a primary impersonation token. 122 // Copies the process token making it a primary impersonation token.
123 // The returned handle will have |desired_access| rights. 123 // The returned handle will have |desired_access| rights.
124 bool CopyProcessToken(DWORD desired_access, ScopedHandle* token_out) { 124 bool CopyProcessToken(DWORD desired_access, ScopedHandle* token_out) {
125 HANDLE temp_handle; 125 ScopedHandle process_token;
126 if (!OpenProcessToken(GetCurrentProcess(), 126 if (!OpenProcessToken(GetCurrentProcess(),
127 TOKEN_DUPLICATE | desired_access, 127 TOKEN_DUPLICATE | desired_access,
128 &temp_handle)) { 128 process_token.Receive())) {
129 LOG_GETLASTERROR(ERROR) << "Failed to open process token"; 129 LOG_GETLASTERROR(ERROR) << "Failed to open process token";
130 return false; 130 return false;
131 } 131 }
132 ScopedHandle process_token(temp_handle);
133 132
133 ScopedHandle copied_token;
134 if (!DuplicateTokenEx(process_token, 134 if (!DuplicateTokenEx(process_token,
135 desired_access, 135 desired_access,
136 NULL, 136 NULL,
137 SecurityImpersonation, 137 SecurityImpersonation,
138 TokenPrimary, 138 TokenPrimary,
139 &temp_handle)) { 139 copied_token.Receive())) {
140 LOG_GETLASTERROR(ERROR) << "Failed to duplicate the process token"; 140 LOG_GETLASTERROR(ERROR) << "Failed to duplicate the process token";
141 return false; 141 return false;
142 } 142 }
143 143
144 token_out->Set(temp_handle); 144 *token_out = copied_token.Pass();
145 return true; 145 return true;
146 } 146 }
147 147
148 // Creates a copy of the current process with SE_TCB_NAME privilege enabled. 148 // Creates a copy of the current process with SE_TCB_NAME privilege enabled.
149 bool CreatePrivilegedToken(ScopedHandle* token_out) { 149 bool CreatePrivilegedToken(ScopedHandle* token_out) {
150 ScopedHandle privileged_token; 150 ScopedHandle privileged_token;
151 DWORD desired_access = TOKEN_ADJUST_PRIVILEGES | TOKEN_IMPERSONATE | 151 DWORD desired_access = TOKEN_ADJUST_PRIVILEGES | TOKEN_IMPERSONATE |
152 TOKEN_DUPLICATE | TOKEN_QUERY; 152 TOKEN_DUPLICATE | TOKEN_QUERY;
153 if (!CopyProcessToken(desired_access, &privileged_token)) { 153 if (!CopyProcessToken(desired_access, &privileged_token)) {
154 return false; 154 return false;
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 ScopedHandle* process_out, 460 ScopedHandle* process_out,
461 ScopedHandle* thread_out) { 461 ScopedHandle* thread_out) {
462 base::FilePath::StringType application_name = binary.value(); 462 base::FilePath::StringType application_name = binary.value();
463 463
464 STARTUPINFOW startup_info; 464 STARTUPINFOW startup_info;
465 memset(&startup_info, 0, sizeof(startup_info)); 465 memset(&startup_info, 0, sizeof(startup_info));
466 startup_info.cb = sizeof(startup_info); 466 startup_info.cb = sizeof(startup_info);
467 if (desktop_name) 467 if (desktop_name)
468 startup_info.lpDesktop = const_cast<char16*>(desktop_name); 468 startup_info.lpDesktop = const_cast<char16*>(desktop_name);
469 469
470 PROCESS_INFORMATION temp_process_info = {}; 470 base::win::ScopedProcessInformation process_info;
471 BOOL result = CreateProcessAsUser(user_token, 471 BOOL result = CreateProcessAsUser(user_token,
472 application_name.c_str(), 472 application_name.c_str(),
473 const_cast<LPWSTR>(command_line.c_str()), 473 const_cast<LPWSTR>(command_line.c_str()),
474 process_attributes, 474 process_attributes,
475 thread_attributes, 475 thread_attributes,
476 inherit_handles, 476 inherit_handles,
477 creation_flags, 477 creation_flags,
478 NULL, 478 NULL,
479 NULL, 479 NULL,
480 &startup_info, 480 &startup_info,
481 &temp_process_info); 481 process_info.Receive());
482 482
483 // CreateProcessAsUser will fail on XP and W2K3 with ERROR_PIPE_NOT_CONNECTED 483 // CreateProcessAsUser will fail on XP and W2K3 with ERROR_PIPE_NOT_CONNECTED
484 // if the user hasn't logged to the target session yet. In such a case 484 // if the user hasn't logged to the target session yet. In such a case
485 // we try to talk to the execution server directly emulating what 485 // we try to talk to the execution server directly emulating what
486 // the undocumented and not-exported advapi32!CreateRemoteSessionProcessW() 486 // the undocumented and not-exported advapi32!CreateRemoteSessionProcessW()
487 // function does. The created process will run under Winlogon'a token instead 487 // function does. The created process will run under Winlogon'a token instead
488 // of |user_token|. Since Winlogon runs as SYSTEM, this suits our needs. 488 // of |user_token|. Since Winlogon runs as SYSTEM, this suits our needs.
489 if (!result && 489 if (!result &&
490 GetLastError() == ERROR_PIPE_NOT_CONNECTED && 490 GetLastError() == ERROR_PIPE_NOT_CONNECTED &&
491 base::win::GetVersion() < base::win::VERSION_VISTA) { 491 base::win::GetVersion() < base::win::VERSION_VISTA) {
492 DWORD session_id; 492 DWORD session_id;
493 DWORD return_length; 493 DWORD return_length;
494 result = GetTokenInformation(user_token, 494 result = GetTokenInformation(user_token,
495 TokenSessionId, 495 TokenSessionId,
496 &session_id, 496 &session_id,
497 sizeof(session_id), 497 sizeof(session_id),
498 &return_length); 498 &return_length);
499 if (result && session_id != 0) { 499 if (result && session_id != 0) {
500 result = CreateRemoteSessionProcess(session_id, 500 result = CreateRemoteSessionProcess(session_id,
501 application_name, 501 application_name,
502 command_line, 502 command_line,
503 creation_flags, 503 creation_flags,
504 desktop_name, 504 desktop_name,
505 &temp_process_info); 505 process_info.Receive());
506 } else { 506 } else {
507 // Restore the error status returned by CreateProcessAsUser(). 507 // Restore the error status returned by CreateProcessAsUser().
508 result = FALSE; 508 result = FALSE;
509 SetLastError(ERROR_PIPE_NOT_CONNECTED); 509 SetLastError(ERROR_PIPE_NOT_CONNECTED);
510 } 510 }
511 } 511 }
512 512
513 if (!result) { 513 if (!result) {
514 LOG_GETLASTERROR(ERROR) << 514 LOG_GETLASTERROR(ERROR) <<
515 "Failed to launch a process with a user token"; 515 "Failed to launch a process with a user token";
516 return false; 516 return false;
517 } 517 }
518 518
519 base::win::ScopedProcessInformation process_info(temp_process_info);
520
521 CHECK(process_info.IsValid()); 519 CHECK(process_info.IsValid());
522 process_out->Set(process_info.TakeProcessHandle()); 520 process_out->Set(process_info.TakeProcessHandle());
523 thread_out->Set(process_info.TakeThreadHandle()); 521 thread_out->Set(process_info.TakeThreadHandle());
524 return true; 522 return true;
525 } 523 }
526 524
527 } // namespace remoting 525 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/win/chromoting_module.cc ('k') | remoting/host/win/unprivileged_process_delegate.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698