Changeset 80569 in vbox
- Timestamp:
- Sep 3, 2019 2:34:21 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 35 edited
-
doc/VBox-CodingGuidelines.cpp (modified) (1 diff)
-
doc/manual/en_US/user_AdvancedTopics.xml (modified) (1 diff)
-
include/iprt/process.h (modified) (3 diffs)
-
src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp (modified) (2 diffs)
-
src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp (modified) (1 diff)
-
src/VBox/Frontends/Common/PasswordInput.cpp (added)
-
src/VBox/Frontends/Common/PasswordInput.h (added)
-
src/VBox/Frontends/VBoxAutostart/Makefile.kmk (modified) (2 diffs)
-
src/VBox/Frontends/VBoxAutostart/VBoxAutostart-win.cpp (modified) (22 diffs)
-
src/VBox/Frontends/VBoxAutostart/VBoxAutostart.h (modified) (4 diffs)
-
src/VBox/Frontends/VBoxAutostart/VBoxAutostartUtils.cpp (modified) (5 diffs)
-
src/VBox/Frontends/VBoxBugReport/VBoxBugReport.cpp (modified) (2 diffs)
-
src/VBox/Frontends/VBoxHeadless/Makefile.kmk (modified) (1 diff)
-
src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp (modified) (2 diffs)
-
src/VBox/Frontends/VBoxManage/Makefile.kmk (modified) (2 diffs)
-
src/VBox/Frontends/VBoxManage/VBoxManage.cpp (modified) (1 diff)
-
src/VBox/Frontends/VBoxManage/VBoxManage.h (modified) (2 diffs)
-
src/VBox/Frontends/VBoxSDL/Makefile.kmk (modified) (2 diffs)
-
src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp (modified) (3 diffs)
-
src/VBox/Main/Makefile.kmk (modified) (3 diffs)
-
src/VBox/Main/idl/VirtualBox.xidl (modified) (2 diffs)
-
src/VBox/Main/include/MachineLaunchVMCommonWorker.h (added)
-
src/VBox/Main/include/VirtualBoxSDSImpl.h (modified) (1 diff)
-
src/VBox/Main/src-all/ExtPackManagerImpl.cpp (modified) (1 diff)
-
src/VBox/Main/src-all/MachineLaunchVMCommonWorker.cpp (added)
-
src/VBox/Main/src-client/ClientTokenHolder.cpp (modified) (1 diff)
-
src/VBox/Main/src-global/win/VirtualBoxSDSImpl.cpp (modified) (4 diffs)
-
src/VBox/Main/src-helper-apps/VBoxExtPackHelperApp.cpp (modified) (1 diff)
-
src/VBox/Main/src-server/ClientToken.cpp (modified) (2 diffs)
-
src/VBox/Main/src-server/MachineImpl.cpp (modified) (3 diffs)
-
src/VBox/Main/src-server/generic/AutostartDb-generic.cpp (modified) (4 diffs)
-
src/VBox/Runtime/common/fuzz/fuzz-observer.cpp (modified) (2 diffs)
-
src/VBox/Runtime/generic/RTProcDaemonize-generic.cpp (modified) (1 diff)
-
src/VBox/Runtime/r3/posix/process-creation-posix.cpp (modified) (3 diffs)
-
src/VBox/Runtime/r3/win/process-win.cpp (modified) (21 diffs)
-
src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp (modified) (10 diffs)
-
src/VBox/ValidationKit/utils/TestExecServ/TestExecService.cpp (modified) (1 diff)
-
src/bldprogs/scmsubversion.cpp (modified) (2 diffs)
-
src/libs/xpcom18a4/nsprpub/pr/src/md/unix/uxproces.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/doc/VBox-CodingGuidelines.cpp
r79974 r80569 629 629 * NULL, // pszAsUser 630 630 * NULL, // pszPassword 631 * NULL, // pExtraData 631 632 * &hProcess); 632 633 * @endcode -
trunk/doc/manual/en_US/user_AdvancedTopics.xml
r78532 r80569 5875 5875 <ulink 5876 5876 url="http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/BPSystemStartup.html">http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/BPSystemStartup.html</ulink>. 5877 </para> 5878 5879 </sect2> 5880 5881 <sect2 id="autostart-windows"> 5882 5883 <title>Windows: Starting the Autostart Service With windows service</title> 5884 5885 <para> 5886 On Windows, the autostarting is implemented as Windows service. 5887 The service is installed for every user with her/his own credentials. 5888 Before installing any autostart services on a system you have to define 5889 the <computeroutput>VBOXAUTOSTART_CONFIG</computeroutput> environment 5890 variable in the system variables with the path to the config file. 5891 The config file has the same format as on Linux, 5892 see <xref linkend="autostart-linux" />, except the user name 5893 can be specified using following formats: "user", "domain\user", 5894 ".\user" and "user@domain". 5895 </para> 5896 5897 <para> 5898 To activate the autostart ability for particular user a member of 5899 administrators group must run the following command: 5900 </para> 5901 5902 <screen>VBoxAutostartSvc install --user=<user> [--password-file=<password_file>]</screen> 5903 5904 <para> 5905 The password file should contain the password followed by a line break. 5906 The rest of the file is ignored. The user will be asked for a password 5907 if the password file is not specified. 5908 </para> 5909 5910 <para> 5911 To remove the autostart ability for particular user a member of 5912 administrators group must run the following command: 5913 </para> 5914 5915 <screen>VBoxAutostartSvc delete --user=<user></screen> 5916 5917 <para> 5918 The user can be specified for both commands using following formats: 5919 "user", "domain\user", ".\user" and "user@domain" 5920 </para> 5921 5922 <para> 5923 Note: 5924 </para> 5925 5926 <para> 5927 If user has changed his password a member of administrators group 5928 must either reinstall the service or change the service credentials 5929 using windows service manager. The autostart service can not be 5930 installed for users with empty passwords due to Windows security policies. 5877 5931 </para> 5878 5932 -
trunk/include/iprt/process.h
r80481 r80569 168 168 * NULL wif pszAsUser is NULL. Whether this is actually 169 169 * used or not depends on the platform. 170 * @param pvExtraData Points to additional data as per @a fFlags: 171 * - RTPROC_FLAGS_DESIRED_SESSION_ID: Pointing to a 172 * uint32_t variable with the desired session ID. 170 173 * @param phProcess Where to store the process handle on successful return. 171 174 * The content is not changed on failure. NULL is allowed. … … 180 183 RTR3DECL(int) RTProcCreateEx(const char *pszExec, const char * const *papszArgs, RTENV hEnv, uint32_t fFlags, 181 184 PCRTHANDLE phStdIn, PCRTHANDLE phStdOut, PCRTHANDLE phStdErr, const char *pszAsUser, 182 const char *pszPassword, PRTPROCESS phProcess);185 const char *pszPassword, void *pvExtraData, PRTPROCESS phProcess); 183 186 184 187 /** @name RTProcCreate and RTProcCreateEx flags … … 228 231 /** Hint that we don't expect to ever want to wait on the process. */ 229 232 #define RTPROC_FLAGS_NO_WAIT RT_BIT(10) 233 /** For use with RTPROC_FLAGS_SERVICE to specify a desired session ID 234 * (Windows only, ignored elsewhere). The @a pvExtraData argument points to 235 * a uint32_t containing the session ID, UINT32_MAX means any session. */ 236 #define RTPROC_FLAGS_DESIRED_SESSION_ID RT_BIT(11) 230 237 /** Valid flag mask. */ 231 #define RTPROC_FLAGS_VALID_MASK UINT32_C(0x 7ff)238 #define RTPROC_FLAGS_VALID_MASK UINT32_C(0xfff) 232 239 /** @} */ 233 240 -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp
r76553 r80569 1298 1298 rc = RTProcCreateEx(szSysprepCmd, papszArgsExp, hEnv, 0 /* fFlags */, 1299 1299 phStdIn, phStdOut, phStdErr, NULL /* pszAsUser */, 1300 NULL /* pszPassword */, phProcess);1300 NULL /* pszPassword */, NULL, phProcess); 1301 1301 vgsvcGstCtrlProcessFreeArgv(papszArgsExp); 1302 1302 } … … 1390 1390 pszUser, 1391 1391 pszPassword && *pszPassword ? pszPassword : NULL, 1392 NULL /*pvExtraData*/, 1392 1393 phProcess); 1393 1394 #ifdef RT_OS_WINDOWS -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp
r79326 r80569 2251 2251 !fAnonymous ? pszUser : NULL, 2252 2252 !fAnonymous ? pSessionThread->StartupInfo.szPassword : NULL, 2253 NULL /*pvExtraData*/, 2253 2254 &pSessionThread->hProcess); 2254 2255 } -
trunk/src/VBox/Frontends/VBoxAutostart/Makefile.kmk
r76553 r80569 22 22 PROGRAMS += VBoxAutostartSvc 23 23 VBoxAutostartSvc_TEMPLATE = VBOXMAINCLIENTEXE 24 VBoxAutostartSvc_INCS = ../Common 24 25 VBoxAutostartSvc_SOURCES = \ 25 26 VBoxAutostartCfg.cpp \ … … 27 28 VBoxAutostartStop.cpp \ 28 29 VBoxAutostartUtils.cpp \ 29 VBoxAutostart-win.cpp 30 VBoxAutostart-win.cpp \ 31 ../Common/PasswordInput.cpp 32 VBoxAutostartSvc_LIBS.win += Secur32.lib 30 33 else 31 34 PROGRAMS += VBoxAutostart -
trunk/src/VBox/Frontends/VBoxAutostart/VBoxAutostart-win.cpp
r76553 r80569 23 23 #include <tchar.h> 24 24 25 #define SECURITY_WIN32 26 #include <Security.h> 27 28 #include <VBox/com/array.h> 25 29 #include <VBox/com/com.h> 26 #include <VBox/com/string.h>27 #include <VBox/com/Guid.h>28 #include <VBox/com/array.h>29 30 #include <VBox/com/ErrorInfo.h> 30 31 #include <VBox/com/errorprint.h> 31 32 #include <VBox/com/Guid.h> 33 #include <VBox/com/listeners.h> 32 34 #include <VBox/com/NativeEventQueue.h> 33 #include <VBox/com/ listeners.h>35 #include <VBox/com/string.h> 34 36 #include <VBox/com/VirtualBox.h> 35 37 36 38 #include <VBox/log.h> 37 39 #include <VBox/version.h> 40 41 #include <iprt/env.h> 38 42 #include <iprt/errcore.h> 43 #include <iprt/getopt.h> 39 44 #include <iprt/initterm.h> 40 45 #include <iprt/mem.h> 41 #include <iprt/getopt.h> 46 #include <iprt/process.h> 47 #include <iprt/path.h> 42 48 #include <iprt/semaphore.h> 43 49 #include <iprt/stream.h> … … 46 52 47 53 #include "VBoxAutostart.h" 54 #include "PasswordInput.h" 48 55 49 56 … … 71 78 /** The semaphore the main service thread is waiting on in autostartSvcWinServiceMain. */ 72 79 static RTSEMEVENTMULTI g_hSupSvcWinEvent = NIL_RTSEMEVENTMULTI; 80 /** The service name is used for send to service main. */ 81 static com::Bstr g_bstrServiceName; 73 82 74 83 … … 77 86 *********************************************************************************************************************************/ 78 87 static SC_HANDLE autostartSvcWinOpenSCManager(const char *pszAction, DWORD dwAccess); 88 89 static int autostartGetProcessDomainUser(com::Utf8Str &aUser) 90 { 91 int rc = VERR_NOT_SUPPORTED; 92 93 RTUTF16 wszUsername[1024] = { 0 }; 94 ULONG cwcUsername = RT_ELEMENTS(wszUsername); 95 char *pszUser = NULL; 96 if (!GetUserNameExW(NameSamCompatible, &wszUsername[0], &cwcUsername)) 97 return RTErrConvertFromWin32(GetLastError()); 98 rc = RTUtf16ToUtf8(wszUsername, &pszUser); 99 aUser = pszUser; 100 RTStrFree(pszUser); 101 return rc; 102 } 103 104 static int autostartGetLocalDomain(com::Utf8Str &aDomain) 105 { 106 RTUTF16 pwszDomain[MAX_COMPUTERNAME_LENGTH + 1] = { 0 }; 107 uint32_t cwcDomainSize = MAX_COMPUTERNAME_LENGTH + 1; 108 if (!GetComputerNameW(pwszDomain, (LPDWORD)&cwcDomainSize)) 109 return RTErrConvertFromWin32(GetLastError()); 110 char *pszDomain = NULL; 111 int rc = RTUtf16ToUtf8(pwszDomain, &pszDomain); 112 aDomain = pszDomain; 113 RTStrFree(pszDomain); 114 return rc; 115 } 116 117 static int autostartGetDomainAndUser(const com::Utf8Str &aDomainAndUser, com::Utf8Str &aDomain, com::Utf8Str &aUser) 118 { 119 size_t offDelim = aDomainAndUser.find("\\"); 120 if (offDelim != aDomainAndUser.npos) 121 { 122 // if only domain is specified 123 if (aDomainAndUser.length() - offDelim == 1) 124 return VERR_INVALID_PARAMETER; 125 126 if (offDelim == 1 && aDomainAndUser[0] == '.') 127 { 128 int rc = autostartGetLocalDomain(aDomain); 129 aUser = aDomainAndUser.substr(offDelim + 1); 130 return rc; 131 } 132 aDomain = aDomainAndUser.substr(0, offDelim); 133 aUser = aDomainAndUser.substr(offDelim + 1); 134 return VINF_SUCCESS; 135 } 136 137 offDelim = aDomainAndUser.find("@"); 138 if (offDelim != aDomainAndUser.npos) 139 { 140 // if only domain is specified 141 if (offDelim == 0) 142 return VERR_INVALID_PARAMETER; 143 144 // with '@' but without domain 145 if (aDomainAndUser.length() - offDelim == 1) 146 { 147 int rc = autostartGetLocalDomain(aDomain); 148 aUser = aDomainAndUser.substr(0, offDelim); 149 return rc; 150 } 151 aDomain = aDomainAndUser.substr(offDelim + 1); 152 aUser = aDomainAndUser.substr(0, offDelim); 153 return VINF_SUCCESS; 154 } 155 156 // only user is specified 157 int rc = autostartGetLocalDomain(aDomain); 158 aUser = aDomainAndUser; 159 return rc; 160 } 161 162 /** Common helper for formatting the service name. */ 163 static void autostartFormatServiceName(const com::Utf8Str &aDomain, const com::Utf8Str &aUser, com::Utf8Str &aServiceName) 164 { 165 aServiceName.printf("%s%s%s", AUTOSTART_SERVICE_NAME, aDomain.c_str(), aUser.c_str()); 166 } 167 168 /** Used by the delete service operation. */ 169 static int autostartGetServiceName(const com::Utf8Str &aDomainAndUser, com::Utf8Str &aServiceName) 170 { 171 com::Utf8Str sDomain; 172 com::Utf8Str sUser; 173 int rc = autostartGetDomainAndUser(aDomainAndUser, sDomain, sUser); 174 if (RT_FAILURE(rc)) 175 return rc; 176 autostartFormatServiceName(sDomain, sUser, aServiceName); 177 return VINF_SUCCESS; 178 } 79 179 80 180 /** … … 228 328 * @param ... Errors codes that should not cause a message to be displayed. 229 329 */ 230 static SC_HANDLE autostartSvcWinOpenService(const char *pszAction, DWORD dwSCMAccess, DWORD dwSVCAccess,330 static SC_HANDLE autostartSvcWinOpenService(const PRTUTF16 pwszServiceName, const char *pszAction, DWORD dwSCMAccess, DWORD dwSVCAccess, 231 331 unsigned cIgnoredErrors, ...) 232 332 { … … 235 335 return NULL; 236 336 237 SC_HANDLE hSvc = OpenService A(hSCM, AUTOSTART_SERVICE_NAME, dwSVCAccess);337 SC_HANDLE hSvc = OpenServiceW(hSCM, pwszServiceName, dwSVCAccess); 238 338 if (hSvc) 239 339 { … … 258 358 break; 259 359 case ERROR_SERVICE_DOES_NOT_EXIST: 260 autostartSvcDisplayError("%s - OpenService failure: The service does not exist. Reinstall it.\n", pszAction); 360 autostartSvcDisplayError("%s - OpenService failure: The service %ls does not exist. Reinstall it.\n", 361 pszAction, pwszServiceName); 261 362 break; 262 363 default: … … 356 457 */ 357 458 bool fVerbose = false; 459 const char *pszUser = NULL; 358 460 static const RTGETOPTDEF s_aOptions[] = 359 461 { 360 { "--verbose", 'v', RTGETOPT_REQ_NOTHING } 462 { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, 463 { "--user", 'u', RTGETOPT_REQ_STRING }, 361 464 }; 362 465 int ch; 363 unsigned iArg = 0;364 466 RTGETOPTUNION Value; 365 467 RTGETOPTSTATE GetState; … … 372 474 fVerbose = true; 373 475 break; 374 case VINF_GETOPT_NOT_OPTION: 375 return autostartSvcDisplayTooManyArgsError("delete", argc, argv, iArg); 476 case 'u': 477 pszUser = Value.psz; 478 break; 376 479 default: 377 return autostartSvcDisplayGetOptError("delete", ch, argc, argv, iArg, &Value); 378 } 379 380 iArg++; 381 } 382 480 return autostartSvcDisplayGetOptError("delete", ch, &Value); 481 } 482 } 483 484 if (!pszUser) 485 return autostartSvcDisplayError("delete - DeleteService failed, user name required.\n"); 486 487 com::Utf8Str sServiceName; 488 int vrc = autostartGetServiceName(pszUser, sServiceName); 489 if (!RT_FAILURE(vrc)) 490 return autostartSvcDisplayError("delete - DeleteService failed, service name for user %s can not be constructed.\n", 491 pszUser); 383 492 /* 384 493 * Create the service. 385 494 */ 386 intrc = RTEXITCODE_FAILURE;387 SC_HANDLE hSvc = autostartSvcWinOpenService( "delete", SERVICE_CHANGE_CONFIG, DELETE,495 RTEXITCODE rc = RTEXITCODE_FAILURE; 496 SC_HANDLE hSvc = autostartSvcWinOpenService(com::Bstr(sServiceName).raw(), "delete", SERVICE_CHANGE_CONFIG, DELETE, 388 497 1, ERROR_SERVICE_DOES_NOT_EXIST); 389 498 if (hSvc) … … 391 500 if (DeleteService(hSvc)) 392 501 { 393 RTPrintf("Successfully deleted the %s service.\n", AUTOSTART_SERVICE_NAME);502 RTPrintf("Successfully deleted the %s service.\n", sServiceName.c_str()); 394 503 rc = RTEXITCODE_SUCCESS; 395 504 } … … 402 511 403 512 if (fVerbose) 404 RTPrintf("The service %s was not installed, nothing to be done.", AUTOSTART_SERVICE_NAME);513 RTPrintf("The service %s was not installed, nothing to be done.", sServiceName.c_str()); 405 514 else 406 RTPrintf("Successfully deleted the %s service.\n", AUTOSTART_SERVICE_NAME);515 RTPrintf("Successfully deleted the %s service.\n", sServiceName.c_str()); 407 516 rc = RTEXITCODE_SUCCESS; 408 517 } … … 425 534 bool fVerbose = false; 426 535 const char *pszUser = NULL; 427 const char *pszPwd = NULL; 536 com::Utf8Str strPwd; 537 const char *pszPwdFile = NULL; 428 538 static const RTGETOPTDEF s_aOptions[] = 429 539 { 430 { "--verbose", 'v', RTGETOPT_REQ_NOTHING },431 { "--user", 'u', RTGETOPT_REQ_STRING },432 { "--password ", 'p', RTGETOPT_REQ_STRING }540 { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, 541 { "--user", 'u', RTGETOPT_REQ_STRING }, 542 { "--password-file", 'p', RTGETOPT_REQ_STRING } 433 543 }; 434 int iArg = 0;435 544 int ch; 436 545 RTGETOPTUNION Value; … … 448 557 break; 449 558 case 'p': 450 pszPwd = Value.psz;559 pszPwdFile = Value.psz; 451 560 break; 452 561 default: 453 return autostartSvcDisplayGetOptError("create", ch, argc, argv, iArg, &Value); 454 } 455 iArg++; 456 } 457 if (iArg != argc) 458 return autostartSvcDisplayTooManyArgsError("create", argc, argv, iArg); 562 return autostartSvcDisplayGetOptError("create", ch, &Value); 563 } 564 } 565 566 if (!pszUser) 567 return autostartSvcDisplayError("Username is missing"); 568 569 if (pszPwdFile) 570 { 571 /* Get password from file. */ 572 RTEXITCODE rcExit = readPasswordFile(pszPwdFile, &strPwd); 573 if (rcExit == RTEXITCODE_FAILURE) 574 return rcExit; 575 } 576 else 577 { 578 /* Get password from console. */ 579 RTEXITCODE rcExit = readPasswordFromConsole(&strPwd, "Enter password:"); 580 if (rcExit == RTEXITCODE_FAILURE) 581 return rcExit; 582 } 583 584 if (strPwd.isEmpty()) 585 return autostartSvcDisplayError("Password is missing"); 586 587 com::Utf8Str sDomain; 588 com::Utf8Str sUserTmp; 589 int vrc = autostartGetDomainAndUser(pszUser, sDomain, sUserTmp); 590 if (RT_FAILURE(vrc)) 591 return autostartSvcDisplayError("create - CreateService failed, failed to get domain and user from string %s (%d).\n", 592 pszUser, vrc); 593 com::Utf8StrFmt sUserFullName("%s\\%s", sDomain.c_str(), sUserTmp.c_str()); 594 com::Utf8StrFmt sDisplayName("%s %s@%s", AUTOSTART_SERVICE_DISPLAY_NAME, sUserTmp.c_str(), sDomain.c_str()); 595 com::Utf8Str sServiceName; 596 autostartFormatServiceName(sDomain, sUserTmp, sServiceName); 459 597 460 598 /* … … 465 603 if (hSCM) 466 604 { 467 char szExecPath[ MAX_PATH];468 if ( GetModuleFileNameA(NULL /* the executable */,szExecPath, sizeof(szExecPath)))605 char szExecPath[RTPATH_MAX]; 606 if (RTProcGetExecutablePath(szExecPath, sizeof(szExecPath))) 469 607 { 470 608 if (fVerbose) 471 609 RTPrintf("Creating the %s service, binary \"%s\"...\n", 472 AUTOSTART_SERVICE_NAME, szExecPath); /* yea, the binary name isn't UTF-8, but wtf. */ 473 474 SC_HANDLE hSvc = CreateServiceA(hSCM, /* hSCManager */ 475 AUTOSTART_SERVICE_NAME, /* lpServiceName */ 476 AUTOSTART_SERVICE_DISPLAY_NAME, /* lpDisplayName */ 610 sServiceName.c_str(), szExecPath); /* yea, the binary name isn't UTF-8, but wtf. */ 611 612 /* 613 * Add service name as command line parameter for the service 614 */ 615 com::Utf8StrFmt sCmdLine("\"%s\" --service=%s", szExecPath, sServiceName.c_str()); 616 SC_HANDLE hSvc = CreateServiceW(hSCM, /* hSCManager */ 617 com::Bstr(sServiceName).raw(), /* lpServiceName */ 618 com::Bstr(sDisplayName).raw(), /* lpDisplayName */ 477 619 SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG, /* dwDesiredAccess */ 478 620 SERVICE_WIN32_OWN_PROCESS, /* dwServiceType ( | SERVICE_INTERACTIVE_PROCESS? ) */ 479 621 SERVICE_AUTO_START, /* dwStartType */ 480 622 SERVICE_ERROR_NORMAL, /* dwErrorControl */ 481 szExecPath,/* lpBinaryPathName */623 com::Bstr(sCmdLine).raw(), /* lpBinaryPathName */ 482 624 NULL, /* lpLoadOrderGroup */ 483 625 NULL, /* lpdwTagId */ 484 626 NULL, /* lpDependencies */ 485 pszUser,/* lpServiceStartName (NULL => LocalSystem) */486 pszPwd);/* lpPassword */627 com::Bstr(sUserFullName).raw(), /* lpServiceStartName (NULL => LocalSystem) */ 628 com::Bstr(strPwd).raw()); /* lpPassword */ 487 629 if (hSvc) 488 630 { 489 RTPrintf("Successfully created the %s service.\n", AUTOSTART_SERVICE_NAME);631 RTPrintf("Successfully created the %s service.\n", sServiceName.c_str()); 490 632 /** @todo Set the service description or it'll look weird in the vista service manager. 491 633 * Anything else that should be configured? Start access or something? */ … … 631 773 } 632 774 633 static DECLCALLBACK(int) autostartWorkerThread(RTTHREAD hThreadSelf, void *pvUser) 634 { 635 RT_NOREF(hThreadSelf, pvUser); 775 static int autostartStartVMs() 776 { 636 777 int rc = autostartSetup(); 637 778 638 /** @todo Implement config options. */ 639 rc = autostartStartMain(NULL); 779 const char *pszConfigFile = RTEnvGet("VBOXAUTOSTART_CONFIG"); 780 if (!pszConfigFile) 781 return autostartSvcLogError("Starting VMs failed. VBOXAUTOSTART_CONFIG environment variable is not defined.\n"); 782 bool fAllow = false; 783 784 PCFGAST pCfgAst = NULL; 785 rc = autostartParseConfig(pszConfigFile, &pCfgAst); 640 786 if (RT_FAILURE(rc)) 641 autostartSvcLogError("Starting VMs failed, rc=%Rrc", rc); 787 return autostartSvcLogError("Starting VMs failed. Failed to parse the config file. Check the access permissions and file structure.\n"); 788 789 PCFGAST pCfgAstPolicy = autostartConfigAstGetByName(pCfgAst, "default_policy"); 790 /* Check default policy. */ 791 if (pCfgAstPolicy) 792 { 793 if ( pCfgAstPolicy->enmType == CFGASTNODETYPE_KEYVALUE 794 && ( !RTStrCmp(pCfgAstPolicy->u.KeyValue.aszValue, "allow") 795 || !RTStrCmp(pCfgAstPolicy->u.KeyValue.aszValue, "deny"))) 796 { 797 if (!RTStrCmp(pCfgAstPolicy->u.KeyValue.aszValue, "allow")) 798 fAllow = true; 799 } 800 else 801 { 802 autostartConfigAstDestroy(pCfgAst); 803 return autostartSvcLogError("'default_policy' must be either 'allow' or 'deny'.\n"); 804 } 805 } 806 807 com::Utf8Str sUser; 808 rc = autostartGetProcessDomainUser(sUser); 809 if (RT_FAILURE(rc)) 810 { 811 autostartConfigAstDestroy(pCfgAst); 812 return autostartSvcLogError("Failed to query username of the process (%Rrc).\n", rc); 813 } 814 815 PCFGAST pCfgAstUser = NULL; 816 for (unsigned i = 0; i < pCfgAst->u.Compound.cAstNodes; i++) 817 { 818 PCFGAST pNode = pCfgAst->u.Compound.apAstNodes[i]; 819 com::Utf8Str sDomain; 820 com::Utf8Str sUserTmp; 821 int rc = autostartGetDomainAndUser(pNode->pszKey, sDomain, sUserTmp); 822 if (RT_FAILURE(rc)) 823 continue; 824 com::Utf8StrFmt sDomainUser("%s\\%s", sDomain.c_str(), sUserTmp.c_str()); 825 if (sDomainUser == sUser) 826 { 827 pCfgAstUser = pNode; 828 break; 829 } 830 } 831 832 if ( pCfgAstUser 833 && pCfgAstUser->enmType == CFGASTNODETYPE_COMPOUND) 834 { 835 pCfgAstPolicy = autostartConfigAstGetByName(pCfgAstUser, "allow"); 836 if (pCfgAstPolicy) 837 { 838 if ( pCfgAstPolicy->enmType == CFGASTNODETYPE_KEYVALUE 839 && ( !RTStrCmp(pCfgAstPolicy->u.KeyValue.aszValue, "true") 840 || !RTStrCmp(pCfgAstPolicy->u.KeyValue.aszValue, "false"))) 841 fAllow = RTStrCmp(pCfgAstPolicy->u.KeyValue.aszValue, "true") == 0; 842 else 843 { 844 autostartConfigAstDestroy(pCfgAst); 845 return autostartSvcLogError("'allow' must be either 'true' or 'false'.\n"); 846 } 847 } 848 } 849 else if (pCfgAstUser) 850 { 851 autostartConfigAstDestroy(pCfgAst); 852 return autostartSvcLogError("Invalid config, user is not a compound node.\n"); 853 } 854 855 if (!fAllow) 856 { 857 autostartConfigAstDestroy(pCfgAst); 858 return autostartSvcLogError("User is not allowed to autostart VMs.\n"); 859 } 860 861 rc = autostartStartMain(pCfgAstUser); 862 autostartConfigAstDestroy(pCfgAst); 863 if (RT_FAILURE(rc)) 864 autostartSvcLogError("Starting VMs failed, rc=%Rrc\n", rc); 642 865 643 866 return rc; … … 651 874 * 652 875 * @param cArgs Argument count. 653 * @param pap szArgsArgument vector.654 */ 655 static VOID WINAPI autostartSvcWinServiceMain(DWORD cArgs, LP TSTR *papszArgs)656 { 657 RT_NOREF(pap szArgs);876 * @param papwszArgs Argument vector. 877 */ 878 static VOID WINAPI autostartSvcWinServiceMain(DWORD cArgs, LPWSTR *papwszArgs) 879 { 880 RT_NOREF(papwszArgs); 658 881 LogFlowFuncEnter(); 659 882 … … 662 885 */ 663 886 Assert(g_u32SupSvcWinStatus == SERVICE_STOPPED); 664 g_hSupSvcWinCtrlHandler = RegisterServiceCtrlHandlerEx A(AUTOSTART_SERVICE_NAME, autostartSvcWinServiceCtrlHandlerEx, NULL);887 g_hSupSvcWinCtrlHandler = RegisterServiceCtrlHandlerExW(g_bstrServiceName.raw(), autostartSvcWinServiceCtrlHandlerEx, NULL); 665 888 if (g_hSupSvcWinCtrlHandler) 666 889 { … … 682 905 if (autostartSvcWinSetServiceStatus(SERVICE_RUNNING, 0, 0)) 683 906 { 684 LogFlow(("autostartSvcWinServiceMain: calling RTSemEventMultiWait\n")); 685 RTTHREAD hWorker; 686 RTThreadCreate(&hWorker, autostartWorkerThread, NULL, 0, RTTHREADTYPE_DEFAULT, 0, "WorkerThread"); 687 688 LogFlow(("autostartSvcWinServiceMain: woke up\n")); 689 err = NO_ERROR; 690 rc = RTSemEventMultiWait(g_hSupSvcWinEvent, RT_INDEFINITE_WAIT); 907 LogFlow(("autostartSvcWinServiceMain: calling autostartStartVMs\n")); 908 rc = autostartStartVMs(); 691 909 if (RT_SUCCESS(rc)) 692 910 { 693 LogFlow(("autostartSvcWinServiceMain: woke up\n")); 694 /** @todo Autostop part. */ 911 LogFlow(("autostartSvcWinServiceMain: done string VMs\n")); 695 912 err = NO_ERROR; 913 rc = RTSemEventMultiWait(g_hSupSvcWinEvent, RT_INDEFINITE_WAIT); 914 if (RT_SUCCESS(rc)) 915 { 916 LogFlow(("autostartSvcWinServiceMain: woke up\n")); 917 /** @todo Autostop part. */ 918 err = NO_ERROR; 919 } 920 else 921 autostartSvcLogError("RTSemEventWait failed, rc=%Rrc", rc); 696 922 } 697 else698 autostartSvcLogError("RTSemEventWait failed, rc=%Rrc", rc);699 923 700 924 autostartShutdown(); … … 703 927 { 704 928 err = GetLastError(); 705 autostartSvcLogError("SetServiceStatus failed, err=% d", err);929 autostartSvcLogError("SetServiceStatus failed, err=%u", err); 706 930 } 707 931 … … 718 942 { 719 943 err = GetLastError(); 720 autostartSvcLogError("SetServiceStatus failed, err=% d", err);944 autostartSvcLogError("SetServiceStatus failed, err=%u", err); 721 945 } 722 946 autostartSvcWinSetServiceStatus(SERVICE_STOPPED, 0, err); 723 947 } 724 948 else 725 autostartSvcLogError("RegisterServiceCtrlHandlerEx failed, err=% d", GetLastError());949 autostartSvcLogError("RegisterServiceCtrlHandlerEx failed, err=%u", GetLastError()); 726 950 727 951 LogFlowFuncLeave(); … … 750 974 static const RTGETOPTDEF s_aOptions[] = 751 975 { 752 { "-- dummy", 'd', RTGETOPT_REQ_NOTHING }976 { "--service", 's', RTGETOPT_REQ_STRING }, 753 977 }; 754 int iArg = 0; 978 979 const char *pszServiceName = NULL; 980 int ch; 981 RTGETOPTUNION Value; 982 RTGETOPTSTATE GetState; 983 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS); 984 while ((ch = RTGetOpt(&GetState, &Value))) 985 { 986 switch (ch) 987 { 988 case 's': 989 pszServiceName = Value.psz; 990 try 991 { 992 g_bstrServiceName = com::Bstr(Value.psz); 993 } 994 catch (...) 995 { 996 autostartSvcLogError("runit failed, service name is not valid utf-8 string or out of memory"); 997 return RTEXITCODE_FAILURE; 998 } 999 break; 1000 default: 1001 return autostartSvcDisplayGetOptError("runit", ch, &Value); 1002 } 1003 } 1004 1005 if (!pszServiceName) 1006 { 1007 autostartSvcLogError("runit failed, service name is missing"); 1008 return RTEXITCODE_FAILURE; 1009 } 1010 1011 /* 1012 * Register the service with the service control manager 1013 * and start dispatching requests from it (all done by the API). 1014 */ 1015 SERVICE_TABLE_ENTRYW const s_aServiceStartTable[] = 1016 { 1017 { g_bstrServiceName.raw(), autostartSvcWinServiceMain }, 1018 { NULL, NULL} 1019 }; 1020 if (StartServiceCtrlDispatcherW(&s_aServiceStartTable[0])) 1021 { 1022 LogFlowFuncLeave(); 1023 return RTEXITCODE_SUCCESS; /* told to quit, so quit. */ 1024 } 1025 1026 DWORD err = GetLastError(); 1027 switch (err) 1028 { 1029 case ERROR_FAILED_SERVICE_CONTROLLER_CONNECT: 1030 autostartSvcWinServiceMain(0, NULL);//autostartSvcDisplayError("Cannot run a service from the command line. Use the 'start' action to start it the right way.\n"); 1031 break; 1032 default: 1033 autostartSvcLogError("StartServiceCtrlDispatcher failed, err=%u", err); 1034 break; 1035 } 1036 return RTEXITCODE_FAILURE; 1037 } 1038 1039 1040 /** 1041 * Show the version info. 1042 * 1043 * @returns RTEXITCODE_SUCCESS. 1044 */ 1045 static RTEXITCODE autostartSvcWinShowVersion(int argc, char **argv) 1046 { 1047 /* 1048 * Parse the arguments. 1049 */ 1050 bool fBrief = false; 1051 static const RTGETOPTDEF s_aOptions[] = 1052 { 1053 { "--brief", 'b', RTGETOPT_REQ_NOTHING } 1054 }; 755 1055 int ch; 756 1056 RTGETOPTUNION Value; … … 760 1060 switch (ch) 761 1061 { 762 default: return autostartSvcDisplayGetOptError("runit", ch, argc, argv, iArg, &Value);763 }764 if (iArg != argc)765 return autostartSvcDisplayTooManyArgsError("runit", argc, argv, iArg);766 767 /*768 * Register the service with the service control manager769 * and start dispatching requests from it (all done by the API).770 */771 static SERVICE_TABLE_ENTRY const s_aServiceStartTable[] =772 {773 { _T(AUTOSTART_SERVICE_NAME), autostartSvcWinServiceMain },774 { NULL, NULL}775 };776 if (StartServiceCtrlDispatcher(&s_aServiceStartTable[0]))777 {778 LogFlowFuncLeave();779 return RTEXITCODE_SUCCESS; /* told to quit, so quit. */780 }781 782 DWORD err = GetLastError();783 switch (err)784 {785 case ERROR_FAILED_SERVICE_CONTROLLER_CONNECT:786 autostartSvcWinServiceMain(0, NULL);//autostartSvcDisplayError("Cannot run a service from the command line. Use the 'start' action to start it the right way.\n");787 break;788 default:789 autostartSvcLogError("StartServiceCtrlDispatcher failed, err=%d", err);790 break;791 }792 return RTEXITCODE_FAILURE;793 }794 795 796 /**797 * Show the version info.798 *799 * @returns RTEXITCODE_SUCCESS.800 */801 static RTEXITCODE autostartSvcWinShowVersion(int argc, char **argv)802 {803 /*804 * Parse the arguments.805 */806 bool fBrief = false;807 static const RTGETOPTDEF s_aOptions[] =808 {809 { "--brief", 'b', RTGETOPT_REQ_NOTHING }810 };811 int iArg = 0;812 int ch;813 RTGETOPTUNION Value;814 RTGETOPTSTATE GetState;815 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);816 while ((ch = RTGetOpt(&GetState, &Value)))817 switch (ch)818 {819 1062 case 'b': fBrief = true; break; 820 default: return autostartSvcDisplayGetOptError("version", ch, argc, argv, iArg, &Value); 821 822 } 823 if (iArg != argc) 824 return autostartSvcDisplayTooManyArgsError("version", argc, argv, iArg); 1063 default: return autostartSvcDisplayGetOptError("version", ch, &Value); 1064 } 825 1065 826 1066 /* -
trunk/src/VBox/Frontends/VBoxAutostart/VBoxAutostart.h
r76582 r80569 253 253 * @todo This should later be replaced by the release logger and callback destination(s). 254 254 */ 255 DECLHIDDEN( void) autostartSvcLogErrorV(const char *pszFormat, va_list va);255 DECLHIDDEN(RTEXITCODE) autostartSvcLogErrorV(const char *pszFormat, va_list va); 256 256 257 257 /** … … 265 265 * @todo This should later be replaced by the release logger and callback destination(s). 266 266 */ 267 DECLHIDDEN( void) autostartSvcLogError(const char *pszFormat, ...);267 DECLHIDDEN(RTEXITCODE) autostartSvcLogError(const char *pszFormat, ...); 268 268 269 269 /** … … 297 297 * @param va Format arguments. 298 298 */ 299 DECLHIDDEN( void) autostartSvcDisplayErrorV(const char *pszFormat, va_list va);299 DECLHIDDEN(RTEXITCODE) autostartSvcDisplayErrorV(const char *pszFormat, va_list va); 300 300 301 301 /** … … 305 305 * @param ... Format arguments. 306 306 */ 307 DECLHIDDEN( void) autostartSvcDisplayError(const char *pszFormat, ...);308 309 /** 310 * Deals with RTGetOpt failure .311 * 312 * @returns 1307 DECLHIDDEN(RTEXITCODE) autostartSvcDisplayError(const char *pszFormat, ...); 308 309 /** 310 * Deals with RTGetOpt failure, i.e. an syntax error. 311 * 312 * @returns RTEXITCODE_SYNTAX 313 313 * @param pszAction The action name. 314 314 * @param rc The RTGetOpt return value. 315 * @param argc The argument count.316 * @param argv The argument vector.317 * @param iArg The argument index.318 315 * @param pValue The value returned by RTGetOpt. 319 316 */ 320 DECLHIDDEN(RTEXITCODE) autostartSvcDisplayGetOptError(const char *pszAction, int rc, int argc, char **argv, int iArg, PCRTGETOPTUNION pValue); 321 322 /** 323 * Bitch about too many arguments (after RTGetOpt stops). 324 * 325 * @returns RTEXITCODE_FAILURE 326 * @param pszAction The action name. 327 * @param argc The argument count. 328 * @param argv The argument vector. 329 * @param iArg The argument index. 330 */ 331 DECLHIDDEN(RTEXITCODE) autostartSvcDisplayTooManyArgsError(const char *pszAction, int argc, char **argv, int iArg); 317 DECLHIDDEN(RTEXITCODE) autostartSvcDisplayGetOptError(const char *pszAction, int rc, PCRTGETOPTUNION pValue); 332 318 333 319 DECLHIDDEN(int) autostartSetup(); -
trunk/src/VBox/Frontends/VBoxAutostart/VBoxAutostartUtils.cpp
r76553 r80569 94 94 } 95 95 96 DECLHIDDEN( void) autostartSvcLogErrorV(const char *pszFormat, va_list va)96 DECLHIDDEN(RTEXITCODE) autostartSvcLogErrorV(const char *pszFormat, va_list va) 97 97 { 98 98 if (*pszFormat) … … 107 107 autostartSvcOsLogStr(pszFormat, AUTOSTARTLOGTYPE_ERROR); 108 108 } 109 } 110 111 DECLHIDDEN(void) autostartSvcLogError(const char *pszFormat, ...) 109 return RTEXITCODE_FAILURE; 110 } 111 112 DECLHIDDEN(RTEXITCODE) autostartSvcLogError(const char *pszFormat, ...) 112 113 { 113 114 va_list va; … … 115 116 autostartSvcLogErrorV(pszFormat, va); 116 117 va_end(va); 118 return RTEXITCODE_FAILURE; 117 119 } 118 120 … … 203 205 } 204 206 205 DECLHIDDEN( void) autostartSvcDisplayErrorV(const char *pszFormat, va_list va)207 DECLHIDDEN(RTEXITCODE) autostartSvcDisplayErrorV(const char *pszFormat, va_list va) 206 208 { 207 209 RTStrmPrintf(g_pStdErr, "VBoxSupSvc error: "); 208 210 RTStrmPrintfV(g_pStdErr, pszFormat, va); 209 211 Log(("autostartSvcDisplayErrorV: %s", pszFormat)); /** @todo format it! */ 210 } 211 212 DECLHIDDEN(void) autostartSvcDisplayError(const char *pszFormat, ...) 212 return RTEXITCODE_FAILURE; 213 } 214 215 DECLHIDDEN(RTEXITCODE) autostartSvcDisplayError(const char *pszFormat, ...) 213 216 { 214 217 va_list va; … … 216 219 autostartSvcDisplayErrorV(pszFormat, va); 217 220 va_end(va); 218 } 219 220 DECLHIDDEN(RTEXITCODE) autostartSvcDisplayGetOptError(const char *pszAction, int rc, int argc, char **argv, int iArg, 221 PCRTGETOPTUNION pValue) 222 { 223 RT_NOREF(pValue); 224 autostartSvcDisplayError("%s - RTGetOpt failure, %Rrc (%d): %s\n", 225 pszAction, rc, rc, iArg < argc ? argv[iArg] : "<null>"); 226 return RTEXITCODE_FAILURE; 227 } 228 229 DECLHIDDEN(RTEXITCODE) autostartSvcDisplayTooManyArgsError(const char *pszAction, int argc, char **argv, int iArg) 230 { 231 RT_NOREF(argc); 232 Assert(iArg < argc); 233 autostartSvcDisplayError("%s - Too many arguments: %s\n", pszAction, argv[iArg]); 234 return RTEXITCODE_FAILURE; 221 return RTEXITCODE_FAILURE; 222 } 223 224 DECLHIDDEN(RTEXITCODE) autostartSvcDisplayGetOptError(const char *pszAction, int rc, PCRTGETOPTUNION pValue) 225 { 226 char szMsg[4096]; 227 RTGetOptFormatError(szMsg, sizeof(szMsg), rc, pValue); 228 autostartSvcDisplayError("%s - %s", pszAction, szMsg); 229 return RTEXITCODE_SYNTAX; 235 230 } 236 231 -
trunk/src/VBox/Frontends/VBoxBugReport/VBoxBugReport.cpp
r78088 r80569 367 367 handleRtError(RTProcCreateEx(m_papszArgs[0], m_papszArgs, RTENV_DEFAULT, 0, 368 368 NULL, &hStdOutErr, &hStdOutErr, 369 NULL, NULL, &hProcess),369 NULL, NULL, NULL, &hProcess), 370 370 "Failed to create process '%s'", m_papszArgs[0]); 371 371 RTPROCSTATUS status; … … 444 444 handleRtError(RTProcCreateEx(m_papszArgs[0], m_papszArgs, RTENV_DEFAULT, 0, 445 445 NULL, &hStdOutErr, &hStdOutErr, 446 NULL, NULL, &hProcess),446 NULL, NULL, NULL, &hProcess), 447 447 "Failed to create process '%s'", m_papszArgs[0]); 448 448 RTPROCSTATUS status; -
trunk/src/VBox/Frontends/VBoxHeadless/Makefile.kmk
r76553 r80569 46 46 VBoxHeadless_TEMPLATE := $(if $(VBOX_WITH_HARDENING),VBOXMAINCLIENTDLL,VBOXMAINCLIENTEXE) 47 47 VBoxHeadless_DEFS += $(if $(VBOX_WITH_RECORDING),VBOX_WITH_RECORDING,) 48 VBoxHeadless_INCS = $(VBOX_GRAPHICS_INCS) 49 VBoxHeadless_SOURCES = VBoxHeadless.cpp 48 VBoxHeadless_INCS = \ 49 $(VBOX_GRAPHICS_INCS) \ 50 ../Common 51 VBoxHeadless_SOURCES = \ 52 VBoxHeadless.cpp \ 53 ../Common/PasswordInput.cpp 50 54 ifdef VBOX_WITH_GUEST_PROPS 51 55 VBoxHeadless_DEFS += VBOX_WITH_GUEST_PROPS -
trunk/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp
r76553 r80569 60 60 #include <signal.h> 61 61 #endif 62 63 #include "PasswordInput.h" 62 64 63 65 //////////////////////////////////////////////////////////////////////////////// … … 525 527 } 526 528 #endif /* VBOX_WITH_RECORDING defined */ 527 528 static RTEXITCODE readPasswordFile(const char *pszFilename, com::Utf8Str *pPasswd)529 {530 size_t cbFile;531 char szPasswd[512];532 int vrc = VINF_SUCCESS;533 RTEXITCODE rcExit = RTEXITCODE_SUCCESS;534 bool fStdIn = !strcmp(pszFilename, "stdin");535 PRTSTREAM pStrm;536 if (!fStdIn)537 vrc = RTStrmOpen(pszFilename, "r", &pStrm);538 else539 pStrm = g_pStdIn;540 if (RT_SUCCESS(vrc))541 {542 vrc = RTStrmReadEx(pStrm, szPasswd, sizeof(szPasswd)-1, &cbFile);543 if (RT_SUCCESS(vrc))544 {545 if (cbFile >= sizeof(szPasswd)-1)546 {547 RTPrintf("Provided password in file '%s' is too long\n", pszFilename);548 rcExit = RTEXITCODE_FAILURE;549 }550 else551 {552 unsigned i;553 for (i = 0; i < cbFile && !RT_C_IS_CNTRL(szPasswd[i]); i++)554 ;555 szPasswd[i] = '\0';556 *pPasswd = szPasswd;557 }558 }559 else560 {561 RTPrintf("Cannot read password from file '%s': %Rrc\n", pszFilename, vrc);562 rcExit = RTEXITCODE_FAILURE;563 }564 if (!fStdIn)565 RTStrmClose(pStrm);566 }567 else568 {569 RTPrintf("Cannot open password file '%s' (%Rrc)\n", pszFilename, vrc);570 rcExit = RTEXITCODE_FAILURE;571 }572 573 return rcExit;574 }575 576 static RTEXITCODE settingsPasswordFile(ComPtr<IVirtualBox> virtualBox, const char *pszFilename)577 {578 com::Utf8Str passwd;579 RTEXITCODE rcExit = readPasswordFile(pszFilename, &passwd);580 if (rcExit == RTEXITCODE_SUCCESS)581 {582 int rc;583 CHECK_ERROR(virtualBox, SetSettingsSecret(com::Bstr(passwd).raw()));584 if (FAILED(rc))585 rcExit = RTEXITCODE_FAILURE;586 }587 588 return rcExit;589 }590 591 529 592 530 #ifdef RT_OS_DARWIN -
trunk/src/VBox/Frontends/VBoxManage/Makefile.kmk
r77883 r80569 66 66 VBoxManage_DEFS.win = _WIN32_WINNT=0x0500 67 67 VBoxManage_INCS = \ 68 $(VBoxManage_0_OUTDIR) 68 $(VBoxManage_0_OUTDIR) \ 69 ../Common 69 70 VBoxManage_INTERMEDIATES = \ 70 71 $(VBoxManage_0_OUTDIR)/VBoxManageBuiltInHelp.h … … 94 95 $(if $(VBOX_WITH_NAT_SERVICE),VBoxManageNATNetwork.cpp,) \ 95 96 $(if $(VBOX_WITH_NAT_SERVICE),../../NetworkServices/NetLib/VBoxNetPortForwardString.cpp,) \ 96 VBoxManageCloud.cpp 97 VBoxManageCloud.cpp \ 98 ../Common/PasswordInput.cpp 97 99 VBoxManage_SOURCES.win = \ 98 100 VBoxManage.rc -
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
r79611 r80569 365 365 } 366 366 367 RTEXITCODE readPasswordFile(const char *pszFilename, com::Utf8Str *pPasswd)368 {369 size_t cbFile;370 char szPasswd[512];371 int vrc = VINF_SUCCESS;372 RTEXITCODE rcExit = RTEXITCODE_SUCCESS;373 bool fStdIn = !strcmp(pszFilename, "stdin");374 PRTSTREAM pStrm;375 if (!fStdIn)376 vrc = RTStrmOpen(pszFilename, "r", &pStrm);377 else378 pStrm = g_pStdIn;379 if (RT_SUCCESS(vrc))380 {381 vrc = RTStrmReadEx(pStrm, szPasswd, sizeof(szPasswd)-1, &cbFile);382 if (RT_SUCCESS(vrc))383 {384 if (cbFile >= sizeof(szPasswd)-1)385 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Provided password in file '%s' is too long", pszFilename);386 else387 {388 unsigned i;389 for (i = 0; i < cbFile && !RT_C_IS_CNTRL(szPasswd[i]); i++)390 ;391 szPasswd[i] = '\0';392 *pPasswd = szPasswd;393 }394 }395 else396 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Cannot read password from file '%s': %Rrc", pszFilename, vrc);397 if (!fStdIn)398 RTStrmClose(pStrm);399 }400 else401 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Cannot open password file '%s' (%Rrc)", pszFilename, vrc);402 403 return rcExit;404 }405 406 static RTEXITCODE settingsPasswordFile(ComPtr<IVirtualBox> virtualBox, const char *pszFilename)407 {408 com::Utf8Str passwd;409 RTEXITCODE rcExit = readPasswordFile(pszFilename, &passwd);410 if (rcExit == RTEXITCODE_SUCCESS)411 {412 CHECK_ERROR2I_STMT(virtualBox, SetSettingsSecret(com::Bstr(passwd).raw()), rcExit = RTEXITCODE_FAILURE);413 }414 415 return rcExit;416 }417 418 RTEXITCODE readPasswordFromConsole(com::Utf8Str *pPassword, const char *pszPrompt, ...)419 {420 RTEXITCODE rcExit = RTEXITCODE_SUCCESS;421 char aszPwdInput[_1K] = { 0 };422 va_list vaArgs;423 424 va_start(vaArgs, pszPrompt);425 int vrc = RTStrmPrintfV(g_pStdOut, pszPrompt, vaArgs);426 if (RT_SUCCESS(vrc))427 {428 bool fEchoOld = false;429 vrc = RTStrmInputGetEchoChars(g_pStdIn, &fEchoOld);430 if (RT_SUCCESS(vrc))431 {432 vrc = RTStrmInputSetEchoChars(g_pStdIn, false);433 if (RT_SUCCESS(vrc))434 {435 vrc = RTStrmGetLine(g_pStdIn, &aszPwdInput[0], sizeof(aszPwdInput));436 if (RT_SUCCESS(vrc))437 *pPassword = aszPwdInput;438 else439 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed read password from command line (%Rrc)", vrc);440 441 int vrc2 = RTStrmInputSetEchoChars(g_pStdIn, fEchoOld);442 AssertRC(vrc2);443 }444 else445 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to disable echoing typed characters (%Rrc)", vrc);446 }447 else448 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to retrieve echo setting (%Rrc)", vrc);449 450 RTStrmPutStr(g_pStdOut, "\n");451 }452 else453 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to print prompt (%Rrc)", vrc);454 va_end(vaArgs);455 456 return rcExit;457 }458 459 367 #endif /* !VBOX_ONLY_DOCS */ 460 368 -
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h
r79796 r80569 37 37 #ifndef VBOX_ONLY_DOCS 38 38 # include "VBoxManageBuiltInHelp.h" 39 # include "PasswordInput.h" 39 40 #endif 40 41 … … 218 219 219 220 #ifndef VBOX_ONLY_DOCS 220 RTEXITCODE readPasswordFile(const char *pszFilename, com::Utf8Str *pPasswd);221 RTEXITCODE readPasswordFromConsole(com::Utf8Str *pPassword, const char *pszPrompt, ...);222 223 221 RTEXITCODE handleInternalCommands(HandlerArg *a); 224 222 #endif /* !VBOX_ONLY_DOCS */ -
trunk/src/VBox/Frontends/VBoxSDL/Makefile.kmk
r76553 r80569 46 46 VBoxSDL.cpp \ 47 47 Framebuffer.cpp \ 48 Helper.cpp 48 Helper.cpp \ 49 ../Common/PasswordInput.cpp 49 50 VBoxSDL_SOURCES.darwin = \ 50 51 VBoxSDLMain-darwin.m \ … … 70 71 VBoxSDL_INCS = \ 71 72 $(VBoxSDL_0_OUTDIR) \ 72 $(VBOX_GRAPHICS_INCS) 73 $(VBOX_GRAPHICS_INCS) \ 74 ../Common 73 75 ifeq ($(filter-out freebsd linux netbsd openbsd solaris,$(KBUILD_TARGET)),) # X11 74 76 VBoxSDL_INCS += \ -
trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp
r78995 r80569 89 89 #include <vector> 90 90 #include <list> 91 92 #include "PasswordInput.h" 91 93 92 94 /* Xlib would re-define our enums */ … … 170 172 static int WaitSDLEvent(SDL_Event *event); 171 173 static void SetFullscreen(bool enable); 172 static RTEXITCODE readPasswordFile(const char *pszFilename, com::Utf8Str *pPasswd);173 static RTEXITCODE settingsPasswordFile(ComPtr<IVirtualBox> virtualBox, const char *pszFilename);174 174 175 175 #ifdef VBOX_WITH_SDL13 … … 3120 3120 RTLogFlush(NULL); 3121 3121 return FAILED(rc) ? 1 : 0; 3122 }3123 3124 static RTEXITCODE readPasswordFile(const char *pszFilename, com::Utf8Str *pPasswd)3125 {3126 size_t cbFile;3127 char szPasswd[512];3128 int vrc = VINF_SUCCESS;3129 RTEXITCODE rcExit = RTEXITCODE_SUCCESS;3130 bool fStdIn = !strcmp(pszFilename, "stdin");3131 PRTSTREAM pStrm;3132 if (!fStdIn)3133 vrc = RTStrmOpen(pszFilename, "r", &pStrm);3134 else3135 pStrm = g_pStdIn;3136 if (RT_SUCCESS(vrc))3137 {3138 vrc = RTStrmReadEx(pStrm, szPasswd, sizeof(szPasswd)-1, &cbFile);3139 if (RT_SUCCESS(vrc))3140 {3141 if (cbFile >= sizeof(szPasswd)-1)3142 {3143 RTPrintf("Provided password in file '%s' is too long\n", pszFilename);3144 rcExit = RTEXITCODE_FAILURE;3145 }3146 else3147 {3148 unsigned i;3149 for (i = 0; i < cbFile && !RT_C_IS_CNTRL(szPasswd[i]); i++)3150 ;3151 szPasswd[i] = '\0';3152 *pPasswd = szPasswd;3153 }3154 }3155 else3156 {3157 RTPrintf("Cannot read password from file '%s': %Rrc\n", pszFilename, vrc);3158 rcExit = RTEXITCODE_FAILURE;3159 }3160 if (!fStdIn)3161 RTStrmClose(pStrm);3162 }3163 else3164 {3165 RTPrintf("Cannot open password file '%s' (%Rrc)\n", pszFilename, vrc);3166 rcExit = RTEXITCODE_FAILURE;3167 }3168 3169 return rcExit;3170 }3171 3172 static RTEXITCODE settingsPasswordFile(ComPtr<IVirtualBox> virtualBox, const char *pszFilename)3173 {3174 com::Utf8Str passwd;3175 RTEXITCODE rcExit = readPasswordFile(pszFilename, &passwd);3176 if (rcExit == RTEXITCODE_SUCCESS)3177 {3178 int rc;3179 CHECK_ERROR(virtualBox, SetSettingsSecret(com::Bstr(passwd).raw()));3180 if (FAILED(rc))3181 rcExit = RTEXITCODE_FAILURE;3182 }3183 3184 return rcExit;3185 3122 } 3186 3123 -
trunk/src/VBox/Main/Makefile.kmk
r80398 r80569 385 385 VBoxSDS_TEMPLATE = VBOXMAINEXE 386 386 VBoxSDS_DEFS += VBOX_COM_OUTOFPROC_MODULE _WIN32_WINNT=0x0600 387 ifdef VBOX_WITH_VBOXSDL 388 VBoxSDS_DEFS += VBOX_WITH_VBOXSDL 389 endif 390 ifdef VBOX_WITH_HEADLESS 391 VBoxSDS_DEFS += VBOX_WITH_HEADLESS 392 endif 393 ifdef VBOX_WITH_QTGUI 394 VBoxSDS_DEFS += VBOX_WITH_QTGUI 395 endif 387 396 VBoxSDS_INCS = \ 388 397 include \ … … 394 403 src-global/win/VBoxSDS.cpp \ 395 404 src-global/win/VirtualBoxSDSImpl.cpp \ 396 src-global/win/VBoxSDS.rc 405 src-global/win/VBoxSDS.rc \ 406 src-all/MachineLaunchVMCommonWorker.cpp 397 407 $(call KB_FN_DO_PASS0_ON_TARGET,VBoxSDS) # Sets VBoxSDS_0_OUTDIR 398 408 … … 553 563 src-server/HostVideoInputDeviceImpl.cpp \ 554 564 src-server/MachineImpl.cpp \ 565 src-all/MachineLaunchVMCommonWorker.cpp \ 555 566 src-server/MachineImplCloneVM.cpp \ 556 567 src-server/MachineImplMoveVM.cpp \ -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r80426 r80569 27033 27033 <interface 27034 27034 name="IVirtualBoxSDS" extends="$unknown" notdual="yes" 27035 uuid=" 152265b8-fe7d-4077-9dd6-032bc3f1c5a3"27035 uuid="bc1a2773-18f2-4066-08ce-1e44d59d84af" 27036 27036 wsmap="suppress" internal="yes" 27037 27037 reservedMethods="0" reservedAttributes="0" … … 27068 27068 <param name="pid" type="long" dir="in"> 27069 27069 <desc>The process ID of the VBoxSVC instance (same as during registration).</desc> 27070 </param> 27071 </method> 27072 27073 <method name="launchVMProcess"> 27074 <desc> 27075 Spawns a new process that will execute the virtual machine in the interactive 27076 windows session of calling user. Any additional checks are performed by created 27077 process itself 27078 27079 If launching the VM succeeds, the new VM process will create its own session 27080 and write-lock the machine for it, preventing conflicting changes from other 27081 processes. If the machine is already locked (because it is already running or 27082 because another session has a write lock), launching the VM process will therefore 27083 fail. Reversely, future attempts to obtain a write lock will also fail while the 27084 machine is running. 27085 27086 Launching a VM process can take some time (a new VM is started in a new process, 27087 for which memory and other resources need to be set up) but the method does 27088 not wait for completion and just returns the PID of created process. 27089 27090 <result name="E_INVALIDARG"> 27091 Some of the parameters are invalid. 27092 </result> 27093 <result name="VBOX_E_IPRT_ERROR"> 27094 Launching process for machine failed. 27095 </result> 27096 </desc> 27097 <param name="machine" type="wstring" dir="in"> 27098 <desc> 27099 The name or id of the machine the VM will start for. 27100 </desc> 27101 </param> 27102 <param name="comment" type="wstring" dir="in"> 27103 <desc> 27104 The comment for VM. 27105 </desc> 27106 </param> 27107 <param name="frontend" type="wstring" dir="in"> 27108 <desc> 27109 Front-end to use for the new VM process. The following are currently supported: 27110 <ul> 27111 <li><tt>"gui"</tt>: VirtualBox Qt GUI front-end</li> 27112 <li><tt>"headless"</tt>: VBoxHeadless (VRDE Server) front-end</li> 27113 <li><tt>"sdl"</tt>: VirtualBox SDL front-end</li> 27114 <li><tt>""</tt>: use the per-VM default frontend if set, otherwise 27115 the global default defined in the system properties. If neither 27116 are set, the API will launch a <tt>"gui"</tt> session, which may 27117 fail if there is no windowing environment available. See 27118 <link to="IMachine::defaultFrontend"/> and 27119 <link to="ISystemProperties::defaultFrontend"/>.</li> 27120 </ul> 27121 </desc> 27122 </param> 27123 <param name="environmentChanges" type="wstring" dir="in"> 27124 <desc> 27125 Environment changes to pass to the VM process, putenv style using newline as separator. 27126 <!-- TODO: make this a safearray so values can safely contain newlines and '\'. --> 27127 </desc> 27128 </param> 27129 <param name="cmdOptions" type="wstring" dir="in"> 27130 <desc> 27131 Additional command line options to pass to the VM process. 27132 </desc> 27133 </param> 27134 <param name="sessionId" type="unsigned long" dir="in"> 27135 <desc> 27136 Windows session where the VM process should be launched. 27137 </desc> 27138 </param> 27139 <param name="pid" type="unsigned long" dir="return"> 27140 <desc>The PID of created process.</desc> 27070 27141 </param> 27071 27142 </method> -
trunk/src/VBox/Main/include/VirtualBoxSDSImpl.h
r76562 r80569 94 94 STDMETHOD(RegisterVBoxSVC)(IVBoxSVCRegistration *aVBoxSVC, LONG aPid, IUnknown **aExistingVirtualBox); 95 95 STDMETHOD(DeregisterVBoxSVC)(IVBoxSVCRegistration *aVBoxSVC, LONG aPid); 96 STDMETHOD(LaunchVMProcess)(IN_BSTR aMachine, IN_BSTR aComment, IN_BSTR aFrontend, IN_BSTR aEnvironmentChanges, 97 IN_BSTR aCmdOptions, ULONG aSessionId, ULONG *aPid); 96 98 /** @} */ 97 99 -
trunk/src/VBox/Main/src-all/ExtPackManagerImpl.cpp
r77624 r80569 2508 2508 NULL /*pszAsUser*/, 2509 2509 NULL /*pszPassword*/, 2510 NULL /*pvExtraData*/, 2510 2511 &hProcess); 2511 2512 if (RT_SUCCESS(vrc)) -
trunk/src/VBox/Main/src-client/ClientTokenHolder.cpp
r77436 r80569 250 250 HANDLE initDoneSem = (HANDLE)data[1]; 251 251 252 HANDLE mutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, Bstr(strSessionId).raw()); 253 AssertMsg(mutex, ("cannot open token, err=%d\n", ::GetLastError())); 254 252 Bstr bstrSessionId(strSessionId); 253 HANDLE mutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, bstrSessionId.raw()); 254 255 //AssertMsg(mutex, ("cannot open token, err=%u\n", ::GetLastError())); 256 AssertMsg(mutex, ("cannot open token %ls, err=%u\n", bstrSessionId.raw(), ::GetLastError())); 255 257 if (mutex) 256 258 { -
trunk/src/VBox/Main/src-global/win/VirtualBoxSDSImpl.cpp
r76592 r80569 31 31 #include <iprt/critsect.h> 32 32 #include <iprt/mem.h> 33 #include <iprt/process.h> 33 34 #include <iprt/system.h> 34 35 … … 37 38 #include <sddl.h> 38 39 #include <lmcons.h> /* UNLEN */ 40 41 #include "MachineLaunchVMCommonWorker.h" 42 43 44 /********************************************************************************************************************************* 45 * Defined Constants And Macros * 46 *********************************************************************************************************************************/ 47 #define INTERACTIVE_SID_FLAG 0x1 48 #define LOCAL_SID_FLAG 0x2 49 #define LOGON_SID_FLAG 0x4 50 #define IS_INTERACTIVE (LOCAL_SID_FLAG|INTERACTIVE_SID_FLAG|LOGON_SID_FLAG) 39 51 40 52 … … 388 400 hrc = E_INVALIDARG; 389 401 LogRel2(("VirtualBoxSDS::deregisterVBoxSVC: returns %Rhrc\n", hrc)); 402 return hrc; 403 } 404 405 406 STDMETHODIMP VirtualBoxSDS::LaunchVMProcess(IN_BSTR aMachine, IN_BSTR aComment, IN_BSTR aFrontend, IN_BSTR aEnvironmentChanges, 407 IN_BSTR aCmdOptions, ULONG aSessionId, ULONG *aPid) 408 { 409 /* 410 * Convert parameters to UTF-8. 411 */ 412 Utf8Str strMachine(aMachine); 413 Utf8Str strComment(aComment); 414 Utf8Str strFrontend(aFrontend); 415 Utf8Str strEnvironmentChanges(aEnvironmentChanges); 416 Utf8Str strCmdOptions(aCmdOptions); 417 418 /* 419 * Impersonate the caller. 420 */ 421 HRESULT hrc = CoImpersonateClient(); 422 if (SUCCEEDED(hrc)) 423 { 424 try 425 { 426 /* 427 * Try launch the VM process as the client. 428 */ 429 RTPROCESS pid; 430 AssertCompile(sizeof(aSessionId) == sizeof(uint32_t)); 431 int vrc = ::MachineLaunchVMCommonWorker(strMachine, strComment, strFrontend, strEnvironmentChanges, 432 strCmdOptions, Utf8Str(), 433 RTPROC_FLAGS_AS_IMPERSONATED_TOKEN | RTPROC_FLAGS_SERVICE 434 | RTPROC_FLAGS_PROFILE | RTPROC_FLAGS_DESIRED_SESSION_ID, 435 &aSessionId, pid); 436 if (RT_SUCCESS(vrc)) 437 { 438 *aPid = (ULONG)pid; 439 LogRel(("VirtualBoxSDS::LaunchVMProcess: launchVM succeeded\n")); 440 } 441 else if (vrc == VERR_INVALID_PARAMETER) 442 { 443 hrc = E_INVALIDARG; 444 LogRel(("VirtualBoxSDS::LaunchVMProcess: launchVM failed: %Rhrc\n", hrc)); 445 } 446 else 447 { 448 hrc = VBOX_E_IPRT_ERROR; 449 LogRel(("VirtualBoxSDS::LaunchVMProcess: launchVM failed: %Rhrc (%Rrc)\n", hrc)); 450 } 451 } 452 catch (...) 453 { 454 hrc = E_UNEXPECTED; 455 } 456 CoRevertToSelf(); 457 } 458 else 459 LogRel(("VirtualBoxSDS::LaunchVMProcess: CoImpersonateClient failed: %Rhrc\n", hrc)); 390 460 return hrc; 391 461 } … … 592 662 } 593 663 664 594 665 #ifdef WITH_WATCHER 595 666 /** -
trunk/src/VBox/Main/src-helper-apps/VBoxExtPackHelperApp.cpp
r77178 r80569 1548 1548 */ 1549 1549 RTPROCESS hProcess; 1550 rc = RTProcCreateEx(papszArgs[iSuArg], &papszArgs[iSuArg], RTENV_DEFAULT, 0 /*fFlags*/, 1551 NULL /*phStd In*/, NULL /*phStdOut*/, NULL /*phStdErr*/, NULL /*pszAsUser*/, NULL /*pszPassword*/,1550 rc = RTProcCreateEx(papszArgs[iSuArg], &papszArgs[iSuArg], RTENV_DEFAULT, 0 /*fFlags*/, NULL /*phStdIn*/, 1551 NULL /*phStdOut*/, NULL /*phStdErr*/, NULL /*pszAsUser*/, NULL /*pszPassword*/, NULL /* pvExtraData*/, 1552 1552 &hProcess); 1553 1553 if (RT_SUCCESS(rc)) -
trunk/src/VBox/Main/src-server/ClientToken.cpp
r76553 r80569 40 40 #include "ClientToken.h" 41 41 #include "MachineImpl.h" 42 43 #ifdef RT_OS_WINDOWS 44 # include <sddl.h> 45 #endif 42 46 43 47 Machine::ClientToken::ClientToken() … … 83 87 #if defined(RT_OS_WINDOWS) 84 88 NOREF(pSessionMachine); 85 Bstr tokenId = pMachine->mData->m_strConfigFileFull; 86 for (size_t i = 0; i < tokenId.length(); i++) 87 if (tokenId.raw()[i] == '\\') 88 tokenId.raw()[i] = '/'; 89 mClientToken = ::CreateMutex(NULL, FALSE, tokenId.raw()); 89 90 /* Get user's SID to use it as part of the mutex name to distinguish shared machine instances 91 * between users 92 */ 93 Utf8Str strUserSid; 94 HANDLE hProcessToken = INVALID_HANDLE_VALUE; 95 if (::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &hProcessToken)) 96 { 97 DWORD dwSize = 0; 98 BOOL fRc = ::GetTokenInformation(hProcessToken, TokenUser, NULL, 0, &dwSize); 99 DWORD dwErr = ::GetLastError(); 100 if (!fRc && dwErr == ERROR_INSUFFICIENT_BUFFER && dwSize > 0) 101 { 102 PTOKEN_USER pTokenUser = (PTOKEN_USER)RTMemTmpAllocZ(dwSize); 103 if (pTokenUser) 104 { 105 if (::GetTokenInformation(hProcessToken, TokenUser, pTokenUser, dwSize, &dwSize)) 106 { 107 PRTUTF16 wstrSid = NULL; 108 if (::ConvertSidToStringSid(pTokenUser->User.Sid, &wstrSid)) 109 { 110 strUserSid = wstrSid; 111 ::LocalFree(wstrSid); 112 } 113 else 114 AssertMsgFailed(("Cannot convert SID to string, err=%u", ::GetLastError())); 115 } 116 else 117 AssertMsgFailed(("Cannot get thread access token information, err=%u", ::GetLastError())); 118 RTMemFree(pTokenUser); 119 } 120 else 121 AssertMsgFailed(("No memory")); 122 } 123 else 124 AssertMsgFailed(("Cannot get thread access token information, err=%u", ::GetLastError())); 125 CloseHandle(hProcessToken); 126 } 127 else 128 AssertMsgFailed(("Cannot get thread access token, err=%u", ::GetLastError())); 129 130 Bstr tokenId = Bstr(Utf8Str("Global\\") + strUserSid + "/" + pMachine->mData->mUuid.toString()); 131 132 /* create security descriptor to allow SYNCHRONIZE access from any windows sessions and users. 133 * otherwise VM can't open the mutex if VBoxSVC and VM are in different session (e.g. some VM 134 * started by autostart service) 135 * 136 * SDDL string contains following ACEs: 137 * CreateOwner : MUTEX_ALL_ACCESS 138 * System : MUTEX_ALL_ACCESS 139 * BuiltInAdministrators : MUTEX_ALL_ACCESS 140 * Everyone : SYNCHRONIZE|MUTEX_MODIFY_STATE 141 */ 142 143 //static const RTUTF16 s_wszSecDesc[] = L"D:(A;;0x1F0001;;;CO)(A;;0x1F0001;;;SY)(A;;0x1F0001;;;BA)(A;;0x100001;;;WD)"; 144 com::BstrFmt bstrSecDesc("O:%sD:(A;;0x1F0001;;;CO)(A;;0x1F0001;;;SY)(A;;0x1F0001;;;BA)", strUserSid.c_str()); 145 PSECURITY_DESCRIPTOR pSecDesc = NULL; 146 //AssertMsgStmt(::ConvertStringSecurityDescriptorToSecurityDescriptor(s_wszSecDesc, SDDL_REVISION_1, &pSecDesc, NULL), 147 AssertMsgStmt(::ConvertStringSecurityDescriptorToSecurityDescriptor(bstrSecDesc.raw(), SDDL_REVISION_1, &pSecDesc, NULL), 148 ("Cannot create security descriptor for token '%ls', err=%u", tokenId.raw(), GetLastError()), 149 pSecDesc = NULL); 150 151 SECURITY_ATTRIBUTES SecAttr; 152 SecAttr.lpSecurityDescriptor = pSecDesc; 153 SecAttr.nLength = sizeof(SecAttr); 154 SecAttr.bInheritHandle = FALSE; 155 mClientToken = ::CreateMutex(&SecAttr, FALSE, tokenId.raw()); 90 156 mClientTokenId = tokenId; 91 AssertMsg(mClientToken, 92 ("Cannot create token '%s', err=%d", 93 mClientTokenId.c_str(), ::GetLastError())); 157 AssertMsg(mClientToken, ("Cannot create token '%s', err=%d", mClientTokenId.c_str(), ::GetLastError())); 158 159 if (pSecDesc) 160 ::LocalFree(pSecDesc); 161 94 162 #elif defined(RT_OS_OS2) 95 163 NOREF(pSessionMachine); -
trunk/src/VBox/Main/src-server/MachineImpl.cpp
r80074 r80569 49 49 #include "MachineImplMoveVM.h" 50 50 #include "ExtPackManagerImpl.h" 51 #include "MachineLaunchVMCommonWorker.h" 51 52 52 53 // generated header … … 7409 7410 } 7410 7411 7411 /* get the path to the executable */7412 char szPath[RTPATH_MAX];7413 RTPathAppPrivateArch(szPath, sizeof(szPath) - 1);7414 size_t cchBufLeft = strlen(szPath);7415 szPath[cchBufLeft++] = RTPATH_DELIMITER;7416 szPath[cchBufLeft] = 0;7417 char *pszNamePart = szPath + cchBufLeft;7418 cchBufLeft = sizeof(szPath) - cchBufLeft;7419 7420 int vrc = VINF_SUCCESS;7421 RTPROCESS pid = NIL_RTPROCESS;7422 7423 RTENV env = RTENV_DEFAULT;7424 7425 if (!strEnvironment.isEmpty())7426 {7427 char *newEnvStr = NULL;7428 7429 do7430 {7431 /* clone the current environment */7432 int vrc2 = RTEnvClone(&env, RTENV_DEFAULT);7433 AssertRCBreakStmt(vrc2, vrc = vrc2);7434 7435 newEnvStr = RTStrDup(strEnvironment.c_str());7436 AssertPtrBreakStmt(newEnvStr, vrc = vrc2);7437 7438 /* put new variables to the environment7439 * (ignore empty variable names here since RTEnv API7440 * intentionally doesn't do that) */7441 char *var = newEnvStr;7442 for (char *p = newEnvStr; *p; ++p)7443 {7444 if (*p == '\n' && (p == newEnvStr || *(p - 1) != '\\'))7445 {7446 *p = '\0';7447 if (*var)7448 {7449 char *val = strchr(var, '=');7450 if (val)7451 {7452 *val++ = '\0';7453 vrc2 = RTEnvSetEx(env, var, val);7454 }7455 else7456 vrc2 = RTEnvUnsetEx(env, var);7457 if (RT_FAILURE(vrc2))7458 break;7459 }7460 var = p + 1;7461 }7462 }7463 if (RT_SUCCESS(vrc2) && *var)7464 vrc2 = RTEnvPutEx(env, var);7465 7466 AssertRCBreakStmt(vrc2, vrc = vrc2);7467 }7468 while (0);7469 7470 if (newEnvStr != NULL)7471 RTStrFree(newEnvStr);7472 }7473 7474 7412 /* Hardening logging */ 7475 7413 #if defined(RT_OS_WINDOWS) && defined(VBOX_WITH_HARDENING) … … 7493 7431 RTFileDelete(strOldStartupLogFile.c_str()); 7494 7432 } 7495 const char *pszSupHardeningLogArg = strSupHardeningLogArg.c_str();7496 7433 #else 7497 const char *pszSupHardeningLogArg = NULL;7434 Utf8Str strSupHardeningLogArg; 7498 7435 #endif 7499 7436 7437 Utf8Str strAppOverride; 7438 #ifdef RT_OS_DARWIN /* Avoid Launch Services confusing this with the selector by using a helper app. */ 7439 strAppOverride = i_getExtraData(Utf8Str("VBoxInternal2/VirtualBoxVMAppOverride")); 7440 #endif 7441 7442 bool fUseVBoxSDS = false; 7500 7443 Utf8Str strCanonicalName; 7501 7444 if (false) 7445 { } 7502 7446 #ifdef VBOX_WITH_QTGUI 7503 if ( !strFrontend.compare("gui", Utf8Str::CaseInsensitive)7504 || !strFrontend.compare("GUI/Qt", Utf8Str::CaseInsensitive)7505 || !strFrontend.compare("separate", Utf8Str::CaseInsensitive)7506 || !strFrontend.compare("gui/separate", Utf8Str::CaseInsensitive)7507 || !strFrontend.compare("GUI/Qt/separate", Utf8Str::CaseInsensitive))7447 else if ( !strFrontend.compare("gui", Utf8Str::CaseInsensitive) 7448 || !strFrontend.compare("GUI/Qt", Utf8Str::CaseInsensitive) 7449 || !strFrontend.compare("separate", Utf8Str::CaseInsensitive) 7450 || !strFrontend.compare("gui/separate", Utf8Str::CaseInsensitive) 7451 || !strFrontend.compare("GUI/Qt/separate", Utf8Str::CaseInsensitive)) 7508 7452 { 7509 7453 strCanonicalName = "GUI/Qt"; 7510 # ifdef RT_OS_DARWIN /* Avoid Launch Services confusing this with the selector by using a helper app. */ 7511 /* Modify the base path so that we don't need to use ".." below. */ 7512 RTPathStripTrailingSlash(szPath); 7513 RTPathStripFilename(szPath); 7514 cchBufLeft = strlen(szPath); 7515 pszNamePart = szPath + cchBufLeft; 7516 cchBufLeft = sizeof(szPath) - cchBufLeft; 7517 7518 # define OSX_APP_NAME "VirtualBoxVM" 7519 # define OSX_APP_PATH_FMT "/Resources/%s.app/Contents/MacOS/VirtualBoxVM" 7520 7521 Utf8Str strAppOverride = i_getExtraData(Utf8Str("VBoxInternal2/VirtualBoxVMAppOverride")); 7522 if ( strAppOverride.contains(".") 7523 || strAppOverride.contains("/") 7524 || strAppOverride.contains("\\") 7525 || strAppOverride.contains(":")) 7526 strAppOverride.setNull(); 7527 Utf8Str strAppPath; 7528 if (!strAppOverride.isEmpty()) 7529 { 7530 strAppPath = Utf8StrFmt(OSX_APP_PATH_FMT, strAppOverride.c_str()); 7531 Utf8Str strFullPath(szPath); 7532 strFullPath.append(strAppPath); 7533 /* there is a race, but people using this deserve the failure */ 7534 if (!RTFileExists(strFullPath.c_str())) 7535 strAppOverride.setNull(); 7536 } 7537 if (strAppOverride.isEmpty()) 7538 strAppPath = Utf8StrFmt(OSX_APP_PATH_FMT, OSX_APP_NAME); 7539 AssertReturn(cchBufLeft > strAppPath.length(), E_UNEXPECTED); 7540 strcpy(pszNamePart, strAppPath.c_str()); 7541 # else 7542 static const char s_szVirtualBox_exe[] = "VirtualBoxVM" HOSTSUFF_EXE; 7543 Assert(cchBufLeft >= sizeof(s_szVirtualBox_exe)); 7544 strcpy(pszNamePart, s_szVirtualBox_exe); 7545 # endif 7546 7547 Utf8Str idStr = mData->mUuid.toString(); 7548 const char *apszArgs[] = 7549 { 7550 szPath, 7551 "--comment", mUserData->s.strName.c_str(), 7552 "--startvm", idStr.c_str(), 7553 "--no-startvm-errormsgbox", 7554 NULL, /* For "--separate". */ 7555 NULL, /* For "--sup-startup-log". */ 7556 NULL 7557 }; 7558 unsigned iArg = 6; 7559 if (fSeparate) 7560 apszArgs[iArg++] = "--separate"; 7561 apszArgs[iArg++] = pszSupHardeningLogArg; 7562 7563 vrc = RTProcCreate(szPath, apszArgs, env, 0, &pid); 7564 } 7565 #else /* !VBOX_WITH_QTGUI */ 7566 if (0) 7567 ; 7568 #endif /* VBOX_WITH_QTGUI */ 7569 7454 fUseVBoxSDS = true; 7455 } 7456 #endif 7457 #ifdef VBOX_WITH_VBOXSDL 7458 else if ( !strFrontend.compare("sdl", Utf8Str::CaseInsensitive) 7459 || !strFrontend.compare("GUI/SDL", Utf8Str::CaseInsensitive) 7460 || !strFrontend.compare("sdl/separate", Utf8Str::CaseInsensitive) 7461 || !strFrontend.compare("GUI/SDL/separate", Utf8Str::CaseInsensitive)) 7462 { 7463 strCanonicalName = "GUI/SDL"; 7464 fUseVBoxSDS = true; 7465 } 7466 #endif 7467 #ifdef VBOX_WITH_HEADLESS 7468 else if ( !strFrontend.compare("headless", Utf8Str::CaseInsensitive) 7469 || !strFrontend.compare("capture", Utf8Str::CaseInsensitive) 7470 || !strFrontend.compare("vrdp", Utf8Str::CaseInsensitive) /* Deprecated. Same as headless. */) 7471 { 7472 strCanonicalName = "headless"; 7473 } 7474 #endif 7570 7475 else 7571 7572 #ifdef VBOX_WITH_VBOXSDL 7573 if ( !strFrontend.compare("sdl", Utf8Str::CaseInsensitive) 7574 || !strFrontend.compare("GUI/SDL", Utf8Str::CaseInsensitive) 7575 || !strFrontend.compare("sdl/separate", Utf8Str::CaseInsensitive) 7576 || !strFrontend.compare("GUI/SDL/separate", Utf8Str::CaseInsensitive)) 7577 { 7578 strCanonicalName = "GUI/SDL"; 7579 static const char s_szVBoxSDL_exe[] = "VBoxSDL" HOSTSUFF_EXE; 7580 Assert(cchBufLeft >= sizeof(s_szVBoxSDL_exe)); 7581 strcpy(pszNamePart, s_szVBoxSDL_exe); 7582 7583 Utf8Str idStr = mData->mUuid.toString(); 7584 const char *apszArgs[] = 7585 { 7586 szPath, 7587 "--comment", mUserData->s.strName.c_str(), 7588 "--startvm", idStr.c_str(), 7589 NULL, /* For "--separate". */ 7590 NULL, /* For "--sup-startup-log". */ 7591 NULL 7592 }; 7593 unsigned iArg = 5; 7594 if (fSeparate) 7595 apszArgs[iArg++] = "--separate"; 7596 apszArgs[iArg++] = pszSupHardeningLogArg; 7597 7598 vrc = RTProcCreate(szPath, apszArgs, env, 0, &pid); 7599 } 7600 #else /* !VBOX_WITH_VBOXSDL */ 7601 if (0) 7602 ; 7603 #endif /* !VBOX_WITH_VBOXSDL */ 7604 7476 return setError(E_INVALIDARG, tr("Invalid frontend name: '%s'"), strFrontend.c_str()); 7477 7478 Utf8Str idStr = mData->mUuid.toString(); 7479 Utf8Str const &strMachineName = mUserData->s.strName; 7480 RTPROCESS pid = NIL_RTPROCESS; 7481 7482 #if !defined(VBOX_WITH_SDS) || !defined(RT_OS_WINDOWS) 7483 RT_NOREF(fUseVBoxSDS); 7484 #else 7485 DWORD idCallerSession = ~(DWORD)0; 7486 if (fUseVBoxSDS) 7487 { 7488 /* 7489 * The VBoxSDS should be used for process launching the VM with 7490 * GUI only if the caller and the VBoxSDS are in different Windows 7491 * sessions and the caller in the interactive one. 7492 */ 7493 fUseVBoxSDS = false; 7494 7495 /* Get windows session of the current process. The process token used 7496 due to several reasons: 7497 1. The token is absent for the current thread except someone set it 7498 for us. 7499 2. Needs to get the id of the session where the process is started. 7500 We only need to do this once, though. */ 7501 static DWORD s_idCurrentSession = ~(DWORD)0; 7502 DWORD idCurrentSession = s_idCurrentSession; 7503 if (idCurrentSession == ~(DWORD)0) 7504 { 7505 HANDLE hCurrentProcessToken = NULL; 7506 if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_READ, &hCurrentProcessToken)) 7507 { 7508 DWORD cbIgn = 0; 7509 if (GetTokenInformation(hCurrentProcessToken, TokenSessionId, &idCurrentSession, sizeof(idCurrentSession), &cbIgn)) 7510 s_idCurrentSession = idCurrentSession; 7511 else 7512 { 7513 idCurrentSession = ~(DWORD)0; 7514 LogRelFunc(("GetTokenInformation/TokenSessionId on self failed: %u\n", GetLastError())); 7515 } 7516 CloseHandle(hCurrentProcessToken); 7517 } 7518 else 7519 LogRelFunc(("OpenProcessToken/self failed: %u\n", GetLastError())); 7520 } 7521 7522 /* get the caller's session */ 7523 HRESULT hrc = CoImpersonateClient(); 7524 if (SUCCEEDED(hrc)) 7525 { 7526 HANDLE hCallerThreadToken; 7527 if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_READ, 7528 FALSE /* OpenAsSelf - for impersonation at SecurityIdentification level */, 7529 &hCallerThreadToken)) 7530 { 7531 SetLastError(NO_ERROR); 7532 DWORD cbIgn = 0; 7533 if (GetTokenInformation(hCallerThreadToken, TokenSessionId, &idCallerSession, sizeof(DWORD), &cbIgn)) 7534 { 7535 /* Only need to use SDS if the session ID differs: */ 7536 if (idCurrentSession != idCallerSession) 7537 { 7538 fUseVBoxSDS = false; 7539 7540 /* Obtain the groups the access token belongs to so we can see if the session is interactive: */ 7541 DWORD cbTokenGroups = 0; 7542 PTOKEN_GROUPS pTokenGroups = NULL; 7543 if ( !GetTokenInformation(hCallerThreadToken, TokenGroups, pTokenGroups, 0, &cbTokenGroups) 7544 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) 7545 pTokenGroups = (PTOKEN_GROUPS)RTMemTmpAllocZ(cbTokenGroups); 7546 if (GetTokenInformation(hCallerThreadToken, TokenGroups, pTokenGroups, cbTokenGroups, &cbTokenGroups)) 7547 { 7548 /* Well-known interactive SID: SECURITY_INTERACTIVE_RID, S-1-5-4: */ 7549 SID_IDENTIFIER_AUTHORITY sidIdNTAuthority = SECURITY_NT_AUTHORITY; 7550 PSID pInteractiveSid = NULL; 7551 if (AllocateAndInitializeSid(&sidIdNTAuthority, 1, 4, 0, 0, 0, 0, 0, 0, 0, &pInteractiveSid)) 7552 { 7553 /* Iterate over the groups looking for the interactive SID: */ 7554 fUseVBoxSDS = false; 7555 for (DWORD dwIndex = 0; dwIndex < pTokenGroups->GroupCount; dwIndex++) 7556 if (EqualSid(pTokenGroups->Groups[dwIndex].Sid, pInteractiveSid)) 7557 { 7558 fUseVBoxSDS = true; 7559 break; 7560 } 7561 FreeSid(pInteractiveSid); 7562 } 7563 } 7564 else 7565 LogRelFunc(("GetTokenInformation/TokenGroups failed: %u\n", GetLastError())); 7566 RTMemTmpFree(pTokenGroups); 7567 } 7568 } 7569 else 7570 LogRelFunc(("GetTokenInformation/TokenSessionId failed: %u\n", GetLastError())); 7571 CloseHandle(hCallerThreadToken); 7572 } 7573 else 7574 LogRelFunc(("OpenThreadToken/client failed: %u\n", GetLastError())); 7575 CoRevertToSelf(); 7576 } 7577 else 7578 LogRelFunc(("CoImpersonateClient failed: %Rhrc\n", hrc)); 7579 } 7580 if (fUseVBoxSDS) 7581 { 7582 /* connect to VBoxSDS */ 7583 ComPtr<IVirtualBoxSDS> pVBoxSDS; 7584 HRESULT rc = pVBoxSDS.createLocalObject(CLSID_VirtualBoxSDS); 7585 if (FAILED(rc)) 7586 return setError(rc, tr("Failed to start the machine '%s'. A connection to VBoxSDS cannot be established"), 7587 strMachineName.c_str()); 7588 7589 /* By default the RPC_C_IMP_LEVEL_IDENTIFY is used for impersonation the client. It allows 7590 ACL checking but restricts an access to system objects e.g. files. Call to CoSetProxyBlanket 7591 elevates the impersonation level up to RPC_C_IMP_LEVEL_IMPERSONATE allowing the VBoxSDS 7592 service to access the files. */ 7593 rc = CoSetProxyBlanket(pVBoxSDS, 7594 RPC_C_AUTHN_DEFAULT, 7595 RPC_C_AUTHZ_DEFAULT, 7596 COLE_DEFAULT_PRINCIPAL, 7597 RPC_C_AUTHN_LEVEL_DEFAULT, 7598 RPC_C_IMP_LEVEL_IMPERSONATE, 7599 NULL, 7600 EOAC_DEFAULT); 7601 if (FAILED(rc)) 7602 return setError(rc, tr("Failed to start the machine '%s'. CoSetProxyBlanket failed"), strMachineName.c_str()); 7603 ULONG uPid = 0; 7604 rc = pVBoxSDS->LaunchVMProcess(Bstr(idStr).raw(), Bstr(strMachineName).raw(), Bstr(strFrontend).raw(), 7605 Bstr(strEnvironment).raw(), Bstr(strSupHardeningLogArg).raw(), 7606 idCallerSession, &uPid); 7607 if (FAILED(rc)) 7608 return setError(rc, tr("Failed to start the machine '%s'. Process creation failed"), strMachineName.c_str()); 7609 pid = (RTPROCESS)uPid; 7610 } 7605 7611 else 7606 7607 #ifdef VBOX_WITH_HEADLESS 7608 if ( !strFrontend.compare("headless", Utf8Str::CaseInsensitive) 7609 || !strFrontend.compare("capture", Utf8Str::CaseInsensitive) 7610 || !strFrontend.compare("vrdp", Utf8Str::CaseInsensitive) /* Deprecated. Same as headless. */ 7611 ) 7612 { 7613 strCanonicalName = "headless"; 7614 /* On pre-4.0 the "headless" type was used for passing "--vrdp off" to VBoxHeadless to let it work in OSE, 7615 * which did not contain VRDP server. In VBox 4.0 the remote desktop server (VRDE) is optional, 7616 * and a VM works even if the server has not been installed. 7617 * So in 4.0 the "headless" behavior remains the same for default VBox installations. 7618 * Only if a VRDE has been installed and the VM enables it, the "headless" will work 7619 * differently in 4.0 and 3.x. 7620 */ 7621 static const char s_szVBoxHeadless_exe[] = "VBoxHeadless" HOSTSUFF_EXE; 7622 Assert(cchBufLeft >= sizeof(s_szVBoxHeadless_exe)); 7623 strcpy(pszNamePart, s_szVBoxHeadless_exe); 7624 7625 Utf8Str idStr = mData->mUuid.toString(); 7626 const char *apszArgs[] = 7627 { 7628 szPath, 7629 "--comment", mUserData->s.strName.c_str(), 7630 "--startvm", idStr.c_str(), 7631 "--vrde", "config", 7632 NULL, /* For "--capture". */ 7633 NULL, /* For "--sup-startup-log". */ 7634 NULL 7635 }; 7636 unsigned iArg = 7; 7637 if (!strFrontend.compare("capture", Utf8Str::CaseInsensitive)) 7638 apszArgs[iArg++] = "--capture"; 7639 apszArgs[iArg++] = pszSupHardeningLogArg; 7640 7641 # ifdef RT_OS_WINDOWS 7642 vrc = RTProcCreate(szPath, apszArgs, env, RTPROC_FLAGS_NO_WINDOW, &pid); 7643 # else 7644 vrc = RTProcCreate(szPath, apszArgs, env, 0, &pid); 7645 # endif 7646 } 7647 #else /* !VBOX_WITH_HEADLESS */ 7648 if (0) 7649 ; 7650 #endif /* !VBOX_WITH_HEADLESS */ 7651 else 7652 { 7653 RTEnvDestroy(env); 7654 return setError(E_INVALIDARG, 7655 tr("Invalid frontend name: '%s'"), 7656 strFrontend.c_str()); 7657 } 7658 7659 RTEnvDestroy(env); 7660 7661 if (RT_FAILURE(vrc)) 7662 return setErrorBoth(VBOX_E_IPRT_ERROR, vrc, 7663 tr("Could not launch a process for the machine '%s' (%Rrc)"), 7664 mUserData->s.strName.c_str(), vrc); 7665 7666 LogFlowThisFunc(("launched.pid=%d(0x%x)\n", pid, pid)); 7612 #endif /* VBOX_WITH_VBOXSDS && RT_OS_WINDOWS */ 7613 { 7614 int vrc = MachineLaunchVMCommonWorker(idStr, strMachineName, strFrontend, strEnvironment, strSupHardeningLogArg, 7615 strAppOverride, 0 /*fFlags*/, NULL /*pvExtraData*/, pid); 7616 if (RT_FAILURE(vrc)) 7617 return setErrorBoth(VBOX_E_IPRT_ERROR, vrc, 7618 tr("Could not launch the VM process for the machine '%s' (%Rrc)"), strMachineName.c_str(), vrc); 7619 } 7620 7621 LogRel(("Launched VM: %u pid: %u (%#x) frontend: %s name: %s\n", 7622 idStr.c_str(), pid, pid, strFrontend.c_str(), strMachineName.c_str())); 7667 7623 7668 7624 if (!fSeparate) -
trunk/src/VBox/Main/src-server/generic/AutostartDb-generic.cpp
r76553 r80569 190 190 rc = autostartModifyDb(true /* fAutostart */, true /* fAddVM */); 191 191 RTCritSectLeave(&this->CritSect); 192 #elif defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) 192 #elif defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS) 193 193 NOREF(pszVMId); /* Not needed */ 194 194 rc = VINF_SUCCESS; … … 210 210 rc = autostartModifyDb(true /* fAutostart */, false /* fAddVM */); 211 211 RTCritSectLeave(&this->CritSect); 212 #elif defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) 212 #elif defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS) 213 213 NOREF(pszVMId); /* Not needed */ 214 214 rc = VINF_SUCCESS; … … 230 230 rc = autostartModifyDb(false /* fAutostart */, true /* fAddVM */); 231 231 RTCritSectLeave(&this->CritSect); 232 #elif defined(RT_OS_DARWIN) 232 #elif defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS) 233 233 NOREF(pszVMId); /* Not needed */ 234 234 rc = VINF_SUCCESS; … … 250 250 rc = autostartModifyDb(false /* fAutostart */, false /* fAddVM */); 251 251 RTCritSectLeave(&this->CritSect); 252 #elif defined(RT_OS_DARWIN) 253 NOREF(pszVMId); /* Not needed */ 254 rc = VINF_SUCCESS; 255 #else 256 NOREF(pszVMId); 257 rc = VERR_NOT_SUPPORTED; 258 #endif 259 260 return rc; 261 } 262 252 #elif defined(RT_OS_DARWIN) || defined (RT_OS_WINDOWS) 253 NOREF(pszVMId); /* Not needed */ 254 rc = VINF_SUCCESS; 255 #else 256 NOREF(pszVMId); 257 rc = VERR_NOT_SUPPORTED; 258 #endif 259 260 return rc; 261 } 262 -
trunk/src/VBox/Runtime/common/fuzz/fuzz-observer.cpp
r77758 r80569 474 474 { 475 475 int rc = RTProcCreateEx(pThis->pszBinary, &pExecCtx->apszArgs[0], pExecCtx->hEnv, 0 /*fFlags*/, &pExecCtx->StdinHandle, 476 &pExecCtx->StdoutHandle, &pExecCtx->StderrHandle, NULL, NULL, &pExecCtx->hProc);476 &pExecCtx->StdoutHandle, &pExecCtx->StderrHandle, NULL, NULL, NULL, &pExecCtx->hProc); 477 477 if (RT_SUCCESS(rc)) 478 478 { … … 577 577 { 578 578 int rc = RTProcCreateEx(pThis->pszBinary, &pExecCtx->apszArgs[0], pExecCtx->hEnv, 0 /*fFlags*/, &pExecCtx->StdinHandle, 579 &pExecCtx->StdoutHandle, &pExecCtx->StderrHandle, NULL, NULL, &pExecCtx->hProc);579 &pExecCtx->StdoutHandle, &pExecCtx->StderrHandle, NULL, NULL, NULL, &pExecCtx->hProc); 580 580 if (RT_SUCCESS(rc)) 581 581 { -
trunk/src/VBox/Runtime/generic/RTProcDaemonize-generic.cpp
r76553 r80569 84 84 RTPROC_FLAGS_DETACHED | RTPROC_FLAGS_SAME_CONTRACT, 85 85 &hStdIn, &hStdOutAndErr, &hStdOutAndErr, 86 NULL /*pszAsUser*/, NULL /*pszPassword*/, NULL /*p hProcess*/);86 NULL /*pszAsUser*/, NULL /*pszPassword*/, NULL /*pExtraData*/, NULL /*phProcess*/); 87 87 88 88 RTFileClose(hStdOutAndErr.u.hFile); -
trunk/src/VBox/Runtime/r3/posix/process-creation-posix.cpp
r79559 r80569 512 512 return RTProcCreateEx(pszExec, papszArgs, Env, fFlags, 513 513 NULL, NULL, NULL, /* standard handles */ 514 NULL /*pszAsUser*/, NULL /* pszPassword*/, 514 NULL /*pszAsUser*/, NULL /* pszPassword*/, NULL /*pvExtraData*/, 515 515 pProcess); 516 516 } … … 682 682 RTR3DECL(int) RTProcCreateEx(const char *pszExec, const char * const *papszArgs, RTENV hEnv, uint32_t fFlags, 683 683 PCRTHANDLE phStdIn, PCRTHANDLE phStdOut, PCRTHANDLE phStdErr, const char *pszAsUser, 684 const char *pszPassword, PRTPROCESS phProcess)684 const char *pszPassword, void *pvExtraData, PRTPROCESS phProcess) 685 685 { 686 686 int rc; … … 704 704 return VERR_PROC_DETACH_NOT_SUPPORTED; 705 705 #endif 706 AssertReturn(pvExtraData == NULL || (fFlags & RTPROC_FLAGS_DESIRED_SESSION_ID), VERR_INVALID_PARAMETER); 706 707 707 708 /* -
trunk/src/VBox/Runtime/r3/win/process-win.cpp
r80503 r80569 140 140 /* advapi32.dll: */ 141 141 static PFNCREATEPROCESSWITHLOGON g_pfnCreateProcessWithLogonW = NULL; 142 static PFNLSALOOKUPNAMES2 g_pfnLsaLookupNames2 = NULL;143 142 static decltype(LogonUserW) *g_pfnLogonUserW = NULL; 144 143 static decltype(CreateProcessAsUserW) *g_pfnCreateProcessAsUserW = NULL; 145 static decltype(LsaNtStatusToWinError) *g_pfnLsaNtStatusToWinError = NULL;146 144 /* user32.dll: */ 147 145 static decltype(OpenWindowStationW) *g_pfnOpenWindowStationW = NULL; … … 353 351 if (RT_FAILURE(rc)) { g_pfnCreateProcessWithLogonW = NULL; Assert(g_enmWinVer <= kRTWinOSType_NT4); } 354 352 355 rc = RTLdrGetSymbol(hMod, "LsaLookupNames2", (void **)&g_pfnLsaLookupNames2);356 if (RT_FAILURE(rc)) { g_pfnLsaLookupNames2 = NULL; Assert(g_enmWinVer <= kRTWinOSType_NT4); }357 358 353 rc = RTLdrGetSymbol(hMod, "LogonUserW", (void **)&g_pfnLogonUserW); 359 354 if (RT_FAILURE(rc)) { g_pfnLogonUserW = NULL; Assert(g_enmWinVer <= kRTWinOSType_NT350); } … … 361 356 rc = RTLdrGetSymbol(hMod, "CreateProcessAsUserW", (void **)&g_pfnCreateProcessAsUserW); 362 357 if (RT_FAILURE(rc)) { g_pfnCreateProcessAsUserW = NULL; Assert(g_enmWinVer <= kRTWinOSType_NT350); } 363 364 rc = RTLdrGetSymbol(hMod, "LsaNtStatusToWinError", (void **)&g_pfnLsaNtStatusToWinError);365 if (RT_FAILURE(rc)) { g_pfnLsaNtStatusToWinError = NULL; Assert(g_enmWinVer <= kRTWinOSType_NT350); }366 358 367 359 RTLdrClose(hMod); … … 413 405 NULL, NULL, NULL, /* standard handles */ 414 406 NULL /*pszAsUser*/, NULL /* pszPassword*/, 415 pProcess);407 NULL /*pvExtraData*/, pProcess); 416 408 } 417 409 … … 482 474 483 475 /** 484 * Get the process token of the process indicated by @a dwPID if the @a pSid 485 * matches.476 * Get the process token of the process indicated by @a dwPID if the @a pSid and 477 * @a idSessionDesired matches. 486 478 * 487 479 * @returns IPRT status code. 488 * @param dwPid The process identifier. 489 * @param pSid The secure identifier of the user. 490 * @param phToken Where to return the a duplicate of the process token 491 * handle on success. (The caller closes it.) 492 */ 493 static int rtProcWinGetProcessTokenHandle(DWORD dwPid, PSID pSid, PHANDLE phToken) 480 * @param dwPid The process identifier. 481 * @param pSid The secure identifier of the user. 482 * @param idDesiredSession The session the process candidate should 483 * preferably belong to, UINT32_MAX if anything 484 * goes. 485 * @param phToken Where to return the a duplicate of the process token 486 * handle on success. (The caller closes it.) 487 */ 488 static int rtProcWinGetProcessTokenHandle(DWORD dwPid, PSID pSid, DWORD idDesiredSession, PHANDLE phToken) 494 489 { 495 490 AssertPtr(pSid); … … 502 497 HANDLE hTokenProc; 503 498 if (OpenProcessToken(hProc, 504 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE 499 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE 505 500 | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE, 506 501 &hTokenProc)) 507 502 { 503 /* 504 * Query the user SID from the token. 505 */ 508 506 SetLastError(NO_ERROR); 509 507 DWORD dwSize = 0; … … 519 517 if (GetTokenInformation(hTokenProc, TokenUser, pTokenUser, dwSize, &dwSize)) 520 518 { 519 /* 520 * Match token user with the user we're want to create a process as. 521 */ 521 522 if ( IsValidSid(pTokenUser->User.Sid) 522 523 && EqualSid(pTokenUser->User.Sid, pSid)) 523 524 { 524 525 /* 525 * So we found the process instance which belongs to the user we want to 526 * to run our new process under. This duplicated token will be used for 527 * the actual CreateProcessAsUserW() call then. 526 * Do we need to match the session ID? 528 527 */ 529 rc = rtProcWinDuplicateToken(hTokenProc, phToken); 528 rc = VINF_SUCCESS; 529 if (idDesiredSession != UINT32_MAX) 530 { 531 DWORD idCurSession = UINT32_MAX; 532 if (GetTokenInformation(hTokenProc, TokenSessionId, &idCurSession, sizeof(DWORD), &dwSize)) 533 rc = idDesiredSession == idCurSession ? VINF_SUCCESS : VERR_NOT_FOUND; 534 else 535 rc = RTErrConvertFromWin32(GetLastError()); 536 } 537 if (RT_SUCCESS(rc)) 538 { 539 /* 540 * Got a match. Duplicate the token. This duplicated token will 541 * be used for the actual CreateProcessAsUserW() call then. 542 */ 543 rc = rtProcWinDuplicateToken(hTokenProc, phToken); 544 } 530 545 } 531 546 else … … 627 642 if ( cbRet > 0 628 643 && _stricmp(pszProcName, papszNames[i]) == 0 629 && RT_SUCCESS(rtProcWinGetProcessTokenHandle(paPids[iPid], pSid, phToken)))644 && RT_SUCCESS(rtProcWinGetProcessTokenHandle(paPids[iPid], pSid, UINT32_MAX, phToken))) 630 645 fFound = true; 631 646 CloseHandle(hProc); … … 645 660 646 661 /** 647 * Finds a one of the processes in @a papszNames running with user @a pSid and 648 * returns a duplicate handle to its token.662 * Finds a one of the processes in @a papszNames running with user @a pSid and possibly 663 * in the required windows session. Returns a duplicate handle to its token. 649 664 * 650 665 * @returns Success indicator. 651 * @param papszNames The process candidates, in prioritized order. 652 * @param pSid The secure identifier of the user. 653 * @param phToken Where to return the token handle - duplicate, 654 * caller closes it on success. 655 */ 656 static bool rtProcWinFindTokenByProcess(const char * const *papszNames, PSID pSid, PHANDLE phToken) 666 * @param papszNames The process candidates, in prioritized order. 667 * @param pSid The secure identifier of the user. 668 * @param idDesiredSession The session the process candidate should 669 * belong to if possible, UINT32_MAX if anything 670 * goes. 671 * @param phToken Where to return the token handle - duplicate, 672 * caller closes it on success. 673 */ 674 static bool rtProcWinFindTokenByProcess(const char * const *papszNames, PSID pSid, uint32_t idDesiredSession, PHANDLE phToken) 657 675 { 658 676 AssertPtr(papszNames); … … 685 703 if (_stricmp(ProcEntry.szExeFile, papszNames[i]) == 0) 686 704 { 687 int rc = rtProcWinGetProcessTokenHandle(ProcEntry.th32ProcessID, pSid, phToken);705 int rc = rtProcWinGetProcessTokenHandle(ProcEntry.th32ProcessID, pSid, idDesiredSession, phToken); 688 706 if (RT_SUCCESS(rc)) 689 707 { … … 1022 1040 Assert(pSidRet); 1023 1041 RTMemTmpFree(pUser); 1042 *prc = VINF_SUCCESS; 1024 1043 return pSidRet; 1025 1044 } … … 1562 1581 RTENV hEnv, DWORD dwCreationFlags, 1563 1582 STARTUPINFOW *pStartupInfo, PROCESS_INFORMATION *pProcInfo, 1564 uint32_t fFlags, const char *pszExec )1583 uint32_t fFlags, const char *pszExec, uint32_t idDesiredSession) 1565 1584 { 1566 1585 /* … … 1614 1633 * For the token search we need a SID. 1615 1634 */ 1616 PSID pSid = NULL; 1617 if ((fFlags & RTPROC_FLAGS_AS_IMPERSONATED_TOKEN) || pwszUser == NULL) 1618 pSid = rtProcWinGetTokenUserSid(hTokenLogon, &rc); 1619 else 1620 { 1621 /** @todo r=bird: why can't we do this in the same manner as in the 1622 * RTPROC_FLAGS_AS_IMPERSONATED_TOKEN case above? */ 1623 1624 /* Try query the SID and domain sizes first. */ 1625 DWORD cbSid = 0; /* Must be zero to query size! */ 1626 DWORD cwcDomain = 0; 1627 SID_NAME_USE SidNameUse = SidTypeUser; 1628 fRc = LookupAccountNameW(NULL, pwszUser, NULL, &cbSid, NULL, &cwcDomain, &SidNameUse); 1629 if (!fRc) 1630 { 1631 dwErr = GetLastError(); 1632 1633 /* 1634 * The errors ERROR_TRUSTED_DOMAIN_FAILURE and ERROR_TRUSTED_RELATIONSHIP_FAILURE 1635 * can happen if an ADC (Active Domain Controller) is offline or not reachable. 1636 * 1637 * Try to handle these errors gracefully by asking the local LSA cache of the 1638 * client OS instead then. For this to work, the desired user must have at 1639 * least logged in once at that client -- otherwise there will be no cached 1640 * authentication available and this fallback will fail. 1641 */ 1642 if ( g_pfnLsaLookupNames2 /* >= Windows XP */ 1643 && ( dwErr == ERROR_TRUSTED_DOMAIN_FAILURE 1644 || dwErr == ERROR_TRUSTED_RELATIONSHIP_FAILURE)) 1645 { 1646 LSA_OBJECT_ATTRIBUTES objAttr; 1647 RT_ZERO(objAttr); 1648 objAttr.Length = sizeof(LSA_OBJECT_ATTRIBUTES); 1649 1650 LSA_HANDLE lsahPolicy; 1651 NTSTATUS ntSts = LsaOpenPolicy(NULL, &objAttr, POLICY_LOOKUP_NAMES, &lsahPolicy); 1652 if (ntSts == STATUS_SUCCESS) 1653 { 1654 RTPROCWINACCOUNTINFO accountInfo; 1655 RT_ZERO(accountInfo); 1656 rc = rtProcWinParseAccountInfo(pwszUser, &accountInfo); 1657 AssertRC(rc); 1658 AssertPtr(accountInfo.pwszUserName); 1659 1660 LSA_UNICODE_STRING lsaUser; 1661 lsaUser.Buffer = accountInfo.pwszUserName; 1662 lsaUser.Length = (USHORT)(RTUtf16Len(accountInfo.pwszUserName) * sizeof(WCHAR)); 1663 lsaUser.MaximumLength = lsaUser.Length; 1664 1665 PLSA_REFERENCED_DOMAIN_LIST pDomainList = NULL; 1666 PLSA_TRANSLATED_SID2 pTranslatedSids = NULL; 1667 ntSts = g_pfnLsaLookupNames2(lsahPolicy, 0 /* Flags */, 1668 1 /* Number of users to lookup */, 1669 &lsaUser, &pDomainList, &pTranslatedSids); 1670 if (ntSts == STATUS_SUCCESS) 1671 { 1672 AssertPtr(pDomainList); 1673 AssertPtr(pTranslatedSids); 1674 # ifdef DEBUG 1675 LogRelFunc(("LsaLookupNames2: cDomains=%u, DomainIndex=%ld, SidUse=%ld\n", 1676 pDomainList->Entries, pTranslatedSids[0].DomainIndex, pTranslatedSids[0].Use)); 1677 # endif 1678 Assert(pTranslatedSids[0].Use == SidTypeUser); 1679 1680 if (pDomainList->Entries) 1681 { 1682 AssertPtr(pDomainList->Domains); 1683 LogRelFunc(("LsaLookupNames2: Domain=%ls\n", 1684 pDomainList->Domains[pTranslatedSids[0].DomainIndex].Name.Buffer)); 1685 } 1686 1687 cbSid = GetLengthSid(pTranslatedSids->Sid) + 16; 1688 Assert(cbSid); 1689 pSid = (PSID)RTMemAllocZ(cbSid); 1690 if (!CopySid(cbSid, pSid, pTranslatedSids->Sid)) 1691 { 1692 dwErr = GetLastError(); 1693 LogRelFunc(("CopySid failed with: %ld\n", dwErr)); 1694 rc = dwErr != NO_ERROR ? RTErrConvertFromWin32(dwErr) : VERR_INTERNAL_ERROR_2; 1695 } 1696 } 1697 else if (g_pfnLsaNtStatusToWinError) 1698 { 1699 dwErr = g_pfnLsaNtStatusToWinError(ntSts); 1700 LogRelFunc(("LsaLookupNames2 failed with: %ld\n", dwErr)); 1701 rc = dwErr != NO_ERROR ? RTErrConvertFromWin32(dwErr) : VERR_INTERNAL_ERROR_2; 1702 } 1703 else 1704 { 1705 LogRelFunc(("LsaLookupNames2 failed with: %#x\n", ntSts)); 1706 rc = RTErrConvertFromNtStatus(ntSts); 1707 } 1708 1709 if (pDomainList) 1710 { 1711 LsaFreeMemory(pDomainList); 1712 pDomainList = NULL; 1713 } 1714 if (pTranslatedSids) 1715 { 1716 LsaFreeMemory(pTranslatedSids); 1717 pTranslatedSids = NULL; 1718 } 1719 1720 rtProcWinFreeAccountInfo(&accountInfo); 1721 LsaClose(lsahPolicy); 1722 } 1723 else if (g_pfnLsaNtStatusToWinError) 1724 { 1725 dwErr = g_pfnLsaNtStatusToWinError(ntSts); 1726 LogRelFunc(("LsaOpenPolicy failed with: %ld\n", dwErr)); 1727 rc = dwErr != NO_ERROR ? RTErrConvertFromWin32(dwErr) : VERR_INTERNAL_ERROR_3; 1728 } 1729 else 1730 { 1731 LogRelFunc(("LsaOpenPolicy failed with: %#x\n", ntSts)); 1732 rc = RTErrConvertFromNtStatus(ntSts); 1733 } 1734 1735 /* Note: pSid will be free'd down below. */ 1736 } 1737 else if (dwErr == ERROR_INSUFFICIENT_BUFFER) 1738 { 1739 /* Allocate memory for the LookupAccountNameW output buffers and do it for real. */ 1740 cbSid = fRc && cbSid != 0 ? cbSid + 16 : _1K; 1741 pSid = (PSID)RTMemAllocZ(cbSid); 1742 if (pSid) 1743 { 1744 cwcDomain = fRc ? cwcDomain + 2 : _4K; 1745 PRTUTF16 pwszDomain = (PRTUTF16)RTMemAllocZ(cwcDomain * sizeof(RTUTF16)); 1746 if (pwszDomain) 1747 { 1748 /* Note: Just pass in the UPN (User Principal Name), e.g. someone@example.com */ 1749 if (!LookupAccountNameW(NULL /*lpSystemName*/, pwszUser, pSid, &cbSid, pwszDomain, &cwcDomain, 1750 &SidNameUse)) 1751 { 1752 dwErr = GetLastError(); 1753 LogRelFunc(("LookupAccountNameW(2) failed with: %ld\n", dwErr)); 1754 rc = dwErr != NO_ERROR ? RTErrConvertFromWin32(dwErr) : VERR_INTERNAL_ERROR_4; 1755 } 1756 1757 RTMemFree(pwszDomain); 1758 } 1759 else 1760 rc = VERR_NO_MEMORY; 1761 1762 /* Note: pSid will be free'd down below. */ 1763 } 1764 else 1765 rc = VERR_NO_MEMORY; 1766 } 1767 else 1768 { 1769 LogRelFunc(("LookupAccountNameW(1) failed with: %ld\n", dwErr)); 1770 rc = dwErr != NO_ERROR ? RTErrConvertFromWin32(dwErr) : VERR_INTERNAL_ERROR_2; 1771 } 1772 } 1773 } 1774 1635 PSID pSid = rtProcWinGetTokenUserSid(hTokenLogon, &rc); 1636 1637 /* 1638 * If we got a valid SID, search the running processes. 1639 */ 1775 1640 /* 1776 1641 * If we got a valid SID, search the running processes. … … 1792 1657 NULL 1793 1658 }; 1794 fFound = rtProcWinFindTokenByProcess(s_papszProcNames, pSid, &hTokenUserDesktop);1659 fFound = rtProcWinFindTokenByProcess(s_papszProcNames, pSid, idDesiredSession, &hTokenUserDesktop); 1795 1660 dwErr = 0; 1796 1661 } … … 1838 1703 { 1839 1704 /* 1840 * Load the profile, if requested. (Must be done prior to 1841 * creating the enviornment.) 1705 * Load the profile, if requested. (Must be done prior to creating the enviornment.) 1706 * 1707 * Note! We don't have sufficient rights when impersonating a user, but we can 1708 * ASSUME the user is logged on and has its profile loaded into HKEY_USERS already. 1842 1709 */ 1843 1710 PROFILEINFOW ProfileInfo; 1844 1711 PRTUTF16 pwszUserFree = NULL; 1845 1712 RT_ZERO(ProfileInfo); 1846 if (fFlags & RTPROC_FLAGS_PROFILE) /** @todo r=bird: We probably don't need to load anything if pwszUser is NULL... */ 1713 /** @todo r=bird: We probably don't need to load anything if pwszUser is NULL... */ 1714 if ((fFlags & (RTPROC_FLAGS_PROFILE | RTPROC_FLAGS_AS_IMPERSONATED_TOKEN)) == RTPROC_FLAGS_PROFILE) 1847 1715 { 1848 1716 if (!pwszUser) … … 1882 1750 rtProcWinStationPrep(hTokenToUse, pStartupInfo, &hOldWinStation); 1883 1751 1884 /* Specify a window station and desktop when start interactive1885 * process from service with an impersonated token. */1886 /** @todo r=bird: Why is this needed? */1887 /** @todo r=bird: Why don't we do this for the non-impersonated token case? */1888 /** @todo r=bird: Remind me, does pure RDP logins get a winSta0 too, or do1889 * the get a mangled name similar to the services? */1890 if ( fFound1891 && (fFlags & (RTPROC_FLAGS_SERVICE | RTPROC_FLAGS_AS_IMPERSONATED_TOKEN))1892 == (RTPROC_FLAGS_SERVICE | RTPROC_FLAGS_AS_IMPERSONATED_TOKEN))1893 pStartupInfo->lpDesktop = L"WinSta0\\default";1894 1895 1752 /* 1896 1753 * Useful KB articles: … … 2199 2056 RTENV hEnv, DWORD dwCreationFlags, 2200 2057 STARTUPINFOW *pStartupInfo, PROCESS_INFORMATION *pProcInfo, 2201 uint32_t fFlags, const char *pszExec )2058 uint32_t fFlags, const char *pszExec, uint32_t idDesiredSession) 2202 2059 { 2203 2060 /* … … 2216 2073 } 2217 2074 return rtProcWinCreateAsUser2(pwszUser, pwszPassword, ppwszExec, pwszCmdLine, 2218 hEnv, dwCreationFlags, pStartupInfo, pProcInfo, fFlags, pszExec );2075 hEnv, dwCreationFlags, pStartupInfo, pProcInfo, fFlags, pszExec, idDesiredSession); 2219 2076 } 2220 2077 … … 2366 2223 RTR3DECL(int) RTProcCreateEx(const char *pszExec, const char * const *papszArgs, RTENV hEnv, uint32_t fFlags, 2367 2224 PCRTHANDLE phStdIn, PCRTHANDLE phStdOut, PCRTHANDLE phStdErr, const char *pszAsUser, 2368 const char *pszPassword, PRTPROCESS phProcess)2225 const char *pszPassword, void *pvExtraData, PRTPROCESS phProcess) 2369 2226 { 2370 2227 /* … … 2381 2238 AssertReturn(!pszPassword || pszAsUser, VERR_INVALID_PARAMETER); 2382 2239 AssertPtrNullReturn(pszPassword, VERR_INVALID_POINTER); 2240 2241 /* Extra data: */ 2242 uint32_t idDesiredSession = UINT32_MAX; 2243 if ( (fFlags & (RTPROC_FLAGS_DESIRED_SESSION_ID | RTPROC_FLAGS_SERVICE)) 2244 == (RTPROC_FLAGS_DESIRED_SESSION_ID | RTPROC_FLAGS_SERVICE)) 2245 { 2246 AssertPtrReturn(pvExtraData, VERR_INVALID_POINTER); 2247 idDesiredSession = *(uint32_t *)pvExtraData; 2248 } 2249 else 2250 AssertReturn(!(fFlags & RTPROC_FLAGS_DESIRED_SESSION_ID), VERR_INVALID_FLAGS); 2383 2251 2384 2252 /* … … 2585 2453 rc = rtProcWinCreateAsUser(pwszUser, pwszPassword, 2586 2454 &pwszExec, pwszCmdLine, hEnv, dwCreationFlags, 2587 &StartupInfo, &ProcInfo, fFlags, pszExec );2455 &StartupInfo, &ProcInfo, fFlags, pszExec, idDesiredSession); 2588 2456 2589 2457 if (pwszPassword && *pwszPassword) -
trunk/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp
r76553 r80569 219 219 RTPROCESS hProc; 220 220 RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, 221 NULL, NULL, NULL, pszAsUser, pszPassword, &hProc), VINF_SUCCESS);221 NULL, NULL, NULL, pszAsUser, pszPassword, NULL, &hProc), VINF_SUCCESS); 222 222 RTPROCSTATUS ProcStatus = { -1, RTPROCEXITREASON_ABEND }; 223 223 RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS); … … 233 233 int rc; 234 234 RTTESTI_CHECK_RC(rc = RTProcCreateEx(g_szExecName, apszArgs, hEnvChange, RTPROC_FLAGS_ENV_CHANGE_RECORD, 235 NULL, NULL, NULL, pszAsUser, pszPassword, &hProc), VINF_SUCCESS);235 NULL, NULL, NULL, pszAsUser, pszPassword, NULL, &hProc), VINF_SUCCESS); 236 236 if (RT_SUCCESS(rc)) 237 237 { … … 248 248 apszArgs[2] = "noinherit"; 249 249 RTTESTI_CHECK_RC(rc = RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, RTPROC_FLAGS_PROFILE, 250 NULL, NULL, NULL, pszAsUser, pszPassword, &hProc), VINF_SUCCESS);250 NULL, NULL, NULL, pszAsUser, pszPassword, NULL, &hProc), VINF_SUCCESS); 251 251 if (RT_SUCCESS(rc)) 252 252 { … … 263 263 RTTESTI_CHECK_RC(rc = RTProcCreateEx(g_szExecName, apszArgs, hEnvChange, 264 264 RTPROC_FLAGS_PROFILE | RTPROC_FLAGS_ENV_CHANGE_RECORD, 265 NULL, NULL, NULL, pszAsUser, pszPassword, &hProc), VINF_SUCCESS);265 NULL, NULL, NULL, pszAsUser, pszPassword, NULL, &hProc), VINF_SUCCESS); 266 266 if (RT_SUCCESS(rc)) 267 267 { … … 386 386 RTPROCESS hProc; 387 387 int rc = RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL, NULL, NULL, 388 "non-existing-user", "wrong-password", &hProc);388 "non-existing-user", "wrong-password", NULL, &hProc); 389 389 if (rc != VERR_AUTHENTICATION_FAILURE && rc != VERR_PRIVILEGE_NOT_HELD && rc != VERR_PROC_TCB_PRIV_NOT_HELD) 390 390 RTTestIFailed("rc=%Rrc", rc); … … 392 392 /* Test for invalid application. */ 393 393 RTTESTI_CHECK_RC(RTProcCreateEx("non-existing-app", apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL, 394 NULL, NULL, NULL, NULL, &hProc), VERR_FILE_NOT_FOUND);394 NULL, NULL, NULL, NULL, NULL, &hProc), VERR_FILE_NOT_FOUND); 395 395 396 396 /* Test a (hopefully) valid user/password logon (given by parameters of this function). */ 397 397 RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL, 398 NULL, NULL, pszUser, pszPassword, &hProc), VINF_SUCCESS);398 NULL, NULL, pszUser, pszPassword, NULL, &hProc), VINF_SUCCESS); 399 399 RTPROCSTATUS ProcStatus = { -1, RTPROCEXITREASON_ABEND }; 400 400 RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS); … … 431 431 RTPROCESS hProc; 432 432 RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, g_apszArgs4, RTENV_DEFAULT, 0 /*fFlags*/, NULL, 433 NULL, NULL, pszAsUser, pszPassword, &hProc), VINF_SUCCESS);433 NULL, NULL, pszAsUser, pszPassword, NULL, &hProc), VINF_SUCCESS); 434 434 RTPROCSTATUS ProcStatus = { -1, RTPROCEXITREASON_ABEND }; 435 435 RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS); … … 472 472 RTPROCESS hProc; 473 473 RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL, 474 &Handle, &Handle, pszAsUser, pszPassword, &hProc), VINF_SUCCESS);474 &Handle, &Handle, pszAsUser, pszPassword, NULL, &hProc), VINF_SUCCESS); 475 475 RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS); 476 476 … … 537 537 RTPROCESS hProc; 538 538 RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL, 539 NULL, &Handle, pszAsUser, pszPassword, &hProc), VINF_SUCCESS);539 NULL, &Handle, pszAsUser, pszPassword, NULL, &hProc), VINF_SUCCESS); 540 540 RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS); 541 541 … … 603 603 RTPROCESS hProc; 604 604 RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL, 605 &Handle, NULL, pszAsUser, pszPassword, &hProc), VINF_SUCCESS);605 &Handle, NULL, pszAsUser, pszPassword, NULL, &hProc), VINF_SUCCESS); 606 606 RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS); 607 607 -
trunk/src/VBox/ValidationKit/utils/TestExecServ/TestExecService.cpp
r79423 r80569 2718 2718 rc = RTProcCreateEx(pszExecName, papszArgs, pTxsExec->hEnv, 0 /*fFlags*/, 2719 2719 pTxsExec->StdIn.phChild, pTxsExec->StdOut.phChild, pTxsExec->StdErr.phChild, 2720 *pszUsername ? pszUsername : NULL, NULL, 2720 *pszUsername ? pszUsername : NULL, NULL, NULL, 2721 2721 &pTxsExec->hProcess); 2722 2722 if (RT_SUCCESS(rc)) -
trunk/src/bldprogs/scmsubversion.cpp
r76553 r80569 419 419 NULL /*pszAsUser*/, 420 420 NULL /*pszPassword*/, 421 NULL /*pvExtraData*/, 421 422 &hProc); 422 423 rc2 = RTHandleClose(&hChildStdErr); AssertRC(rc2); … … 556 557 NULL /*pszAsUser*/, 557 558 NULL /*pszPassword*/, 559 NULL /*pvExtraData*/, 558 560 &hProc); 559 561 -
trunk/src/libs/xpcom18a4/nsprpub/pr/src/md/unix/uxproces.c
r33404 r80569 601 601 vrc = RTProcCreateEx(path, (const char **)argv, childEnv, 602 602 RTPROC_FLAGS_DETACHED, pStdIn, pStdOut, pStdErr, 603 NULL /* pszAsUser */, NULL /* pszPassword */, 603 NULL /* pszAsUser */, NULL /* pszPassword */, NULL /* pExtraData */, 604 604 NULL /* phProcess */); 605 605 if (newEnv != RTENV_DEFAULT) {
Note:
See TracChangeset
for help on using the changeset viewer.

