Changeset 57869 in vbox
- Timestamp:
- Sep 23, 2015 1:53:53 PM (9 years ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/process-creation-posix.cpp
r57358 r57869 41 41 #include <signal.h> 42 42 #include <grp.h> 43 #include <paths.h> 44 #include <pwd.h> 43 45 #if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) 44 46 # include <crypt.h> 45 # include <pwd.h>46 47 # include <shadow.h> 47 48 #endif … … 103 104 pw = getpwnam(pszUser); 104 105 if (!pw) 105 return VERR_ PERMISSION_DENIED;106 return VERR_AUTHENTICATION_FAILURE; 106 107 107 108 if (!pszPasswd) … … 127 128 } 128 129 if (!fCorrect) 129 return VERR_ PERMISSION_DENIED;130 return VERR_AUTHENTICATION_FAILURE; 130 131 131 132 *pGid = pw->pw_gid; … … 138 139 139 140 if (getpwnam_r(pszUser, &pw, szBuf, sizeof(szBuf), &ppw) != 0 || ppw == NULL) 140 return VERR_ PERMISSION_DENIED;141 return VERR_AUTHENTICATION_FAILURE; 141 142 142 143 if (!pszPasswd) … … 151 152 char *pszEncPasswd = crypt(pszPasswd, ppw->pw_passwd); 152 153 if (strcmp(pszEncPasswd, ppw->pw_passwd)) 153 return VERR_ PERMISSION_DENIED;154 return VERR_AUTHENTICATION_FAILURE; 154 155 155 156 *pGid = ppw->pw_gid; … … 159 160 #else 160 161 NOREF(pszUser); NOREF(pszPasswd); NOREF(pGid); NOREF(pUid); 161 return VERR_ PERMISSION_DENIED;162 return VERR_AUTHENTICATION_FAILURE; 162 163 #endif 163 164 } … … 271 272 NULL /*pszAsUser*/, NULL /* pszPassword*/, 272 273 pProcess); 274 } 275 276 277 /** 278 * Adjust the profile environment after forking the child process and changing 279 * the UID. 280 * 281 * @returns IRPT status code. 282 * @param hEnvToUse The environment we're going to use with execve. 283 * @param fFlags The process creation flags. 284 * @param hEnv The environment passed in by the user. 285 */ 286 static int rtProcPosixAdjustProfileEnvFromChild(RTENV hEnvToUse, uint32_t fFlags, RTENV hEnv) 287 { 288 int rc = VINF_SUCCESS; 289 #ifdef RT_OS_DARWIN 290 if ( RT_SUCCESS(rc) 291 && (!(fFlags & RTPROC_FLAGS_ENV_CHANGE_RECORD) || RTEnvExistEx(hEnv, "TMPDIR")) ) 292 { 293 char szValue[_4K]; 294 rc = confstr(_SC_DARWIN_USER_TEMP_DIR, szValue, sizeof(szValue)); 295 if (rc > 0 && rc < sizeof(szValue)) 296 { 297 char *pszTmp 298 rc = RTStrCurrentCPToUtf8(&pszTmp, achBuf); 299 if (RT_SUCCESS(rc)) 300 { 301 rc = RTEnvSetEx(hEnvToUse, "TMPDIR", pszTmp); 302 RTStrFree(pszTmp); 303 } 304 } 305 else 306 rc = VERR_BUFFER_OVERFLOW; 307 } 308 #endif 309 return rc; 310 } 311 312 313 /** 314 * Create a very very basic environment for a user. 315 * 316 * @returns IPRT status code. 317 * @param phEnvToUse Where to return the created environment. 318 * @param pszUser The user name for the profile. 319 */ 320 static int rtProcPosixCreateProfileEnv(PRTENV phEnvToUse, const char *pszUser) 321 { 322 struct passwd Pwd; 323 struct passwd *pPwd = NULL; 324 char achBuf[_4K]; 325 int rc; 326 errno = 0; 327 if (pszUser) 328 rc = getpwnam_r(pszUser, &Pwd, achBuf, sizeof(achBuf), &pPwd); 329 else 330 rc = getpwuid_r(getuid(), &Pwd, achBuf, sizeof(achBuf), &pPwd); 331 if (rc == 0 && pPwd) 332 { 333 char *pszDir; 334 rc = RTStrCurrentCPToUtf8(&pszDir, pPwd->pw_dir); 335 if (RT_SUCCESS(rc)) 336 { 337 char *pszShell; 338 rc = RTStrCurrentCPToUtf8(&pszShell, pPwd->pw_shell); 339 if (RT_SUCCESS(rc)) 340 { 341 char *pszUserFree = NULL; 342 if (!pszUser) 343 { 344 rc = RTStrCurrentCPToUtf8(&pszUserFree, pPwd->pw_name); 345 if (RT_SUCCESS(rc)) 346 pszUser = pszUserFree; 347 } 348 if (RT_SUCCESS(rc)) 349 { 350 rc = RTEnvCreate(phEnvToUse); 351 if (RT_SUCCESS(rc)) 352 { 353 RTENV hEnvToUse = *phEnvToUse; 354 355 rc = RTEnvSetEx(hEnvToUse, "HOME", pszDir); 356 if (RT_SUCCESS(rc)) 357 rc = RTEnvSetEx(hEnvToUse, "SHELL", pszShell); 358 if (RT_SUCCESS(rc)) 359 rc = RTEnvSetEx(hEnvToUse, "USER", pszUser); 360 if (RT_SUCCESS(rc)) 361 rc = RTEnvSetEx(hEnvToUse, "LOGNAME", pszUser); 362 363 if (RT_SUCCESS(rc)) 364 rc = RTEnvSetEx(hEnvToUse, "PATH", pPwd->pw_uid == 0 ? _PATH_STDPATH : _PATH_DEFPATH); 365 366 if (RT_SUCCESS(rc)) 367 { 368 RTStrPrintf(achBuf, sizeof(achBuf), "%s/%s", _PATH_MAILDIR, pszUser); 369 rc = RTEnvSetEx(hEnvToUse, "MAIL", achBuf); 370 } 371 372 #ifdef RT_OS_DARWIN 373 if (RT_SUCCESS(rc) && !pszUserFree) 374 { 375 rc = confstr(_SC_DARWIN_USER_TEMP_DIR, achBuf, sizeof(achBuf)); 376 if (rc > 0 && rc < sizeof(achBuf)) 377 { 378 char *pszTmp 379 rc = RTStrCurrentCPToUtf8(&pszTmp, achBuf); 380 if (RT_SUCCESS(rc)) 381 { 382 rc = RTEnvSetEx(hEnvToUse, "TMPDIR", pszTmp); 383 RTStrFree(pszTmp); 384 } 385 } 386 else 387 rc = VERR_BUFFER_OVERFLOW; 388 } 389 #endif 390 391 /** @todo load /etc/environment, /etc/profile.env and ~/.pam_environment? */ 392 393 if (RT_FAILURE(rc)) 394 RTEnvDestroy(hEnvToUse); 395 } 396 RTStrFree(pszUserFree); 397 } 398 RTStrFree(pszShell); 399 } 400 RTStrFree(pszDir); 401 } 402 } 403 else 404 rc = errno ? RTErrConvertFromErrno(errno) : VERR_ACCESS_DENIED; 405 return rc; 273 406 } 274 407 … … 292 425 } 293 426 427 /** 428 * Cleans up the environment on the way out. 429 */ 430 static int rtProcPosixCreateReturn(int rc, RTENV hEnvToUse, RTENV hEnv) 431 { 432 if (hEnvToUse != hEnv) 433 RTEnvDestroy(hEnvToUse); 434 return rc; 435 } 436 294 437 295 438 RTR3DECL(int) RTProcCreateEx(const char *pszExec, const char * const *papszArgs, RTENV hEnv, uint32_t fFlags, … … 307 450 AssertReturn(!(fFlags & RTPROC_FLAGS_DETACHED) || !phProcess, VERR_INVALID_PARAMETER); 308 451 AssertReturn(hEnv != NIL_RTENV, VERR_INVALID_PARAMETER); 309 const char * const *papszEnv = RTEnvGetExecEnvP(hEnv);310 AssertPtrReturn(papszEnv, VERR_INVALID_HANDLE);311 452 AssertPtrReturn(papszArgs, VERR_INVALID_PARAMETER); 312 /** @todo search the PATH (add flag for this). */313 453 AssertPtrNullReturn(pszAsUser, VERR_INVALID_POINTER); 314 454 AssertReturn(!pszAsUser || *pszAsUser, VERR_INVALID_PARAMETER); … … 379 519 380 520 /* 521 * Create the child environment if either RTPROC_FLAGS_PROFILE or 522 * RTPROC_FLAGS_ENV_CHANGE_RECORD are in effect. 523 */ 524 RTENV hEnvToUse = hEnv; 525 if ( (fFlags & (RTPROC_FLAGS_ENV_CHANGE_RECORD | RTPROC_FLAGS_PROFILE)) 526 && ( (fFlags & RTPROC_FLAGS_ENV_CHANGE_RECORD) 527 || hEnv == RTENV_DEFAULT) ) 528 { 529 if (fFlags & RTPROC_FLAGS_PROFILE) 530 rc = rtProcPosixCreateProfileEnv(&hEnvToUse, pszAsUser); 531 else 532 rc = RTEnvClone(&hEnvToUse, RTENV_DEFAULT); 533 if (RT_SUCCESS(rc)) 534 { 535 if ((fFlags & RTPROC_FLAGS_ENV_CHANGE_RECORD) && hEnv != RTENV_DEFAULT) 536 rc = RTEnvApplyChanges(hEnvToUse, hEnv); 537 if (RT_FAILURE(rc)) 538 RTEnvDestroy(hEnvToUse); 539 } 540 if (RT_FAILURE(rc)) 541 return rc; 542 } 543 544 /* 381 545 * Check for execute access to the file. 382 546 */ … … 384 548 if (access(pszExec, X_OK)) 385 549 { 550 rc = errno; 386 551 if ( !(fFlags & RTPROC_FLAGS_SEARCH_PATH) 387 || errno!= ENOENT552 || rc != ENOENT 388 553 || RTPathHavePath(pszExec) ) 389 return RTErrConvertFromErrno(errno); 390 391 /* search */ 392 char *pszPath = RTEnvDupEx(hEnv, "PATH"); 393 rc = RTPathTraverseList(pszPath, ':', rtPathFindExec, (void *)pszExec, &szRealExec[0]); 394 RTStrFree(pszPath); 554 rc = RTErrConvertFromErrno(rc); 555 else 556 { 557 /* search */ 558 char *pszPath = RTEnvDupEx(hEnvToUse, "PATH"); 559 rc = RTPathTraverseList(pszPath, ':', rtPathFindExec, (void *)pszExec, &szRealExec[0]); 560 RTStrFree(pszPath); 561 if (RT_SUCCESS(rc)) 562 pszExec = szRealExec; 563 else 564 rc = rc == VERR_END_OF_STRING ? VERR_FILE_NOT_FOUND : rc; 565 } 566 395 567 if (RT_FAILURE(rc)) 396 return rc == VERR_END_OF_STRING ? VERR_FILE_NOT_FOUND : rc; 397 pszExec = szRealExec; 568 return rtProcPosixCreateReturn(rc, hEnvToUse, hEnv); 398 569 } 399 570 400 571 pid_t pid = -1; 572 const char * const *papszEnv = RTEnvGetExecEnvP(hEnvToUse); 573 AssertPtrReturn(papszEnv, rtProcPosixCreateReturn(VERR_INVALID_HANDLE, hEnvToUse, hEnv)); 574 401 575 402 576 /* … … 418 592 templateFd = rtSolarisContractPreFork(); 419 593 if (templateFd == -1) 420 return VERR_OPEN_FAILED;594 return rtProcPosixCreateReturn(VERR_OPEN_FAILED, hEnvToUse, hEnv); 421 595 } 422 596 # endif /* RT_OS_SOLARIS */ … … 427 601 if (!(fFlags & RTPROC_FLAGS_SAME_CONTRACT)) 428 602 rtSolarisContractPostForkChild(templateFd); 429 # endif /* RT_OS_SOLARIS */603 # endif 430 604 setsid(); /* see comment above */ 431 605 … … 435 609 else 436 610 { 437 # ifdef RT_OS_SOLARIS611 # ifdef RT_OS_SOLARIS 438 612 if (!(fFlags & RTPROC_FLAGS_SAME_CONTRACT)) 439 613 rtSolarisContractPostForkParent(templateFd, pid); 440 # endif /* RT_OS_SOLARIS */614 # endif 441 615 if (pid > 0) 442 616 { … … 454 628 /* Assume that something wasn't found. No detailed info. */ 455 629 if (status) 456 return VERR_PROCESS_NOT_FOUND;630 return rtProcPosixCreateReturn(VERR_PROCESS_NOT_FOUND, hEnvToUse, hEnv); 457 631 if (phProcess) 458 632 *phProcess = 0; 459 return VINF_SUCCESS;460 } 461 return RTErrConvertFromErrno(errno);633 return rtProcPosixCreateReturn(VINF_SUCCESS, hEnvToUse, hEnv); 634 } 635 return rtProcPosixCreateReturn(RTErrConvertFromErrno(errno), hEnvToUse, hEnv); 462 636 } 463 637 } … … 560 734 if (phProcess) 561 735 *phProcess = pid; 562 return VINF_SUCCESS;736 return rtProcPosixCreateReturn(VINF_SUCCESS, hEnvToUse, hEnv); 563 737 } 564 738 } … … 577 751 templateFd = rtSolarisContractPreFork(); 578 752 if (templateFd == -1) 579 return VERR_OPEN_FAILED;753 return rtProcPosixCreateReturn(VERR_OPEN_FAILED, hEnvToUse, hEnv); 580 754 } 581 755 #endif /* RT_OS_SOLARIS */ … … 627 801 } 628 802 #endif 803 804 /* 805 * Some final profile environment tweaks, if running as user. 806 */ 807 if ( (fFlags & RTPROC_FLAGS_PROFILE) 808 && pszAsUser 809 && ( (fFlags & RTPROC_FLAGS_ENV_CHANGE_RECORD) 810 || hEnv == RTENV_DEFAULT) ) 811 { 812 rc = rtProcPosixAdjustProfileEnvFromChild(hEnvToUse, fFlags, hEnv); 813 papszEnv = RTEnvGetExecEnvP(hEnvToUse); 814 if (RT_FAILURE(rc) || !papszEnv) 815 { 816 if (fFlags & RTPROC_FLAGS_DETACHED) 817 _Exit(126); 818 else 819 exit(126); 820 } 821 } 629 822 630 823 /* … … 694 887 if (phProcess) 695 888 *phProcess = pid; 696 return VINF_SUCCESS;889 return rtProcPosixCreateReturn(VINF_SUCCESS, hEnvToUse, hEnv); 697 890 } 698 891 /* For a detached process this happens in the temp process, so … … 700 893 if (fFlags & RTPROC_FLAGS_DETACHED) 701 894 _Exit(124); 702 return RTErrConvertFromErrno(errno);703 } 704 705 return VERR_NOT_IMPLEMENTED;895 return rtProcPosixCreateReturn(RTErrConvertFromErrno(errno), hEnvToUse, hEnv); 896 } 897 898 return rtProcPosixCreateReturn(VERR_NOT_IMPLEMENTED, hEnvToUse, hEnv); 706 899 } 707 900 -
trunk/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp
r57843 r57869 90 90 91 91 int cErrors = 0; 92 char szValue[_1 K];92 char szValue[_16K]; 93 93 94 94 /* … … 166 166 } 167 167 168 #if 0168 #if 1 169 169 /* For manual testing. */ 170 170 if (strcmp(argv[2],"noinherit-change-record") == 0) … … 178 178 { 179 179 char szVarNm[_1K]; 180 char szValue[_16K];181 180 rc = RTEnvGetByIndexEx(hEnv, i, szVarNm, sizeof(szVarNm), szValue, sizeof(szValue)); 182 181 if (RT_SUCCESS(rc)) … … 707 706 if (pszAsUser) 708 707 tstRTCreateProcEx5(pszAsUser, pszPassword); 709 #ifdef RT_OS_WINDOWS710 708 tstRTCreateProcEx6(pszAsUser, pszPassword); 711 #endif712 709 713 710 /** @todo Cover files, ++ */
Note:
See TracChangeset
for help on using the changeset viewer.