VBoxExtPackHelperApp.cpp revision 108008bf37ebb349b5b04dacfe73da99dbb0106c
* available from http://www.virtualbox.org. This file is free software;
#include "include/ExtPackUtil.h"
#ifdef RT_OS_WINDOWS
# ifdef DEBUG
# include <Sddl.h>
#ifdef RT_OS_DARWIN
#if !defined(RT_OS_OS2)
# include <stdio.h>
# include <errno.h>
# if !defined(RT_OS_WINDOWS)
# define WITH_ELEVATION
#ifdef WITH_ELEVATION
#ifdef IN_RT_R3
switch (ch)
, RTProcShortName());
return RTEXITCODE_SUCCESS;
return RTEXITCODE_SUCCESS;
return RTEXITCODE_SUCCESS;
return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to construct temporary extension pack path: %Rrc", rc);
return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to rename the extension pack directory: %Rrc", rc);
return RTEXITCODE_SUCCESS;
#if !defined(RT_OS_WINDOWS)
return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to set directory permissions: %Rrc ('%s')", rc, pszDir);
return RTEXITCODE_SUCCESS;
static RTEXITCODE ValidateMemberOfExtPack(const char *pszName, RTVFSOBJTYPE enmType, RTVFSOBJ hVfsObj)
return RTEXITCODE_SUCCESS;
static RTEXITCODE ValidateUnpackedExtPack(const char *pszDir, const char *pszTarball, const char *pszExtPackName)
return RTMsgErrorExit(RTEXITCODE_FAILURE, "Hardening check failed with %Rrc: %s", rc, ErrInfo.Core.pszMsg);
return RTEXITCODE_SUCCESS;
return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to create directory '%s': %Rrc", pszDstDirName, rc);
return RTEXITCODE_SUCCESS;
return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsIoStrmQueryInfo failed with %Rrc on '%s'", rc, pszDstFilename);
uint32_t fFlags = RTFILE_O_WRITE | RTFILE_O_DENY_ALL | RTFILE_O_CREATE | (0600 << RTFILE_O_CREATE_MODE_SHIFT);
return RTEXITCODE_SUCCESS;
RTMsgError("Failed to set the mode of '%s' to %RTfmode: %Rrc", pszDstFilename, ObjInfo.Attr.fMode, rc);
return RTEXITCODE_FAILURE;
static RTEXITCODE UnpackExtPack(RTFILE hTarballFile, const char *pszDirDst, RTMANIFEST hValidManifest,
const char *pszTarball)
int rc = RTPathAbs(pszDirDst, szDstPath, sizeof(szDstPath) - VBOX_EXTPACK_MAX_MEMBER_NAME_LENGTH - 2);
return rcExit;
char *pszName;
rc = RTManifestEqualsEx(hUnpackManifest, hValidManifest, NULL /*papszIgnoreEntries*/, NULL /*papszIgnoreAttr*/,
return rcExit;
static RTEXITCODE ValidateExtPackTarball(RTFILE hTarballFile, const char *pszExtPackName, const char *pszTarball,
return RTEXITCODE_SUCCESS;
static RTEXITCODE DoInstall2(const char *pszBaseDir, const char *pszCertDir, const char *pszTarball,
return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTFileQueryInfo failed with %Rrc on '%s'", rc, pszTarball);
RTStrPrintf(&szTmpPath[cchTmpPath], sizeof(szTmpPath) - cchTmpPath, "-_-inst-%u", (uint32_t)RTProcSelf());
if (!fReplace)
return RTMsgErrorExit(RTEXITCODE_FAILURE, "Unexpected RTPathQueryInfoEx status code %Rrc for '%s'", rc, szFinalPath);
return RTMsgErrorExit(RTEXITCODE_FAILURE, "Unexpected RTPathQueryInfoEx status code %Rrc for '%s'", rc, szFinalPath);
return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to create temporary directory: %Rrc ('%s')", rc, szTmpPath);
&& fReplace
return rcExit;
bool fReplace = false;
int ch;
switch (ch)
if (pszBaseDir)
if (pszCertDir)
if (pszName)
if (pszTarball)
return RTMsgErrorExit(RTEXITCODE_SYNTAX, "The --tarball-fd value is out of range: %#RX64", ValueUnion.u64);
fReplace = true;
if (!pszName)
if (!pszBaseDir)
if (!pszCertDir)
if (!pszTarball)
if (!pstrMangledName)
rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to open the extension pack tarball: %Rrc ('%s')", rc, pszTarball);
delete pstrMangledName;
return rcExit;
int ch;
switch (ch)
if (pszBaseDir)
if (pszName)
if (!pszName)
if (!pszBaseDir)
if (!pstrMangledName)
delete pstrMangledName;
return RTEXITCODE_SUCCESS;
return rcExit;
int ch;
switch (ch)
if (pszBaseDir)
if (!pszBaseDir)
return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed open the base directory: %Rrc ('%s')", rc, pszBaseDir);
bool fCandidate = false;
if ( pszMarker
if (fCandidate)
rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPathJoin failed with %Rrc for '%s'", rc, Entry.szName);
cCleaned++;
if (!cCleaned)
return rcExit;
#ifdef WITH_ELEVATION
static const char * const s_apszPaths[] =
#ifdef RT_OS_SOLARIS
int rc;
if (!cbRead)
if (fComplain)
static RTEXITCODE RelaunchElevatedNative(const char *pszExecPath, const char **papszArgs, int cSuArgs, int cMyArgs,
int iCmd)
#ifdef RT_OS_WINDOWS
char *pszCmdLine;
static char s_szPrompt[] = "VirtualBox needs further rights to make changes to your installation.\n\n";
NULL);
&pSocketStrm);
if (!cbRead)
int rc;
else if ( fHaveDisplayVar
else if (fHaveDisplayVar)
RTMsgError("Unable to locate 'pkexec', 'pksu' or 'su+xterm'. Try perform the operation using VBoxManage running as root");
RTMsgError("Unable to locate 'pkexec'. Try perform the operation using VBoxManage running as root");
&hProcess);
return rcExit;
char const **papszArgs = (char const **)RTMemTmpAllocZ((cSuArgs + cArgs + 1) * sizeof(const char *));
if (papszArgs)
return rcExit;
*pfElevated = false;
# if defined(RT_OS_WINDOWS)
return RTMsgErrorExit(RTEXITCODE_FAILURE, "OpenProcessToken failed: %u (%#x)", GetLastError(), GetLastError());
if (AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminGrpSid))
# ifdef DEBUG
# ifdef DEBUG
rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "GetTokenInformation(TokenGroups,cb) failed: %u (%#x)", GetLastError(), GetLastError());
rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "GetTokenInformation(TokenGroups,0) failed: %u (%#x)", GetLastError(), GetLastError());
rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "AllocateAndInitializeSid failed: %u (%#x)", GetLastError(), GetLastError());
if (fIsAdmin)
DWORD dwIntegrityLevel = *GetSidSubAuthority(pSidAndAttr->Sid, *GetSidSubAuthorityCount(pSidAndAttr->Sid) - 1U);
*pfElevated = true;
rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "GetTokenInformation failed: %u (%#x)", GetLastError(), GetLastError());
rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "GetTokenInformation failed: %u (%#x)", GetLastError(), GetLastError());
rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Membership in the Administrators group is required to perform this action");
return rcExit;
return RTEXITCODE_SUCCESS;
#ifdef WITH_ELEVATION
bool fElevated;
return rcExit;
#ifdef WITH_ELEVATION
switch (ch)
case CMD_INSTALL:
case CMD_UNINSTALL:
case CMD_CLEANUP:
#ifdef WITH_ELEVATION
if (!fElevated)
switch (ch)
case CMD_INSTALL:
case CMD_UNINSTALL:
case CMD_CLEANUP:
switch (rcExit)
case RTEXITCODE_SUCCESS:
return rcExit;
#ifdef WITH_ELEVATION
case OPT_ELEVATED:
fElevated = true;
case OPT_STDERR:
case OPT_STDOUT:
if (!pFile)
#ifdef RT_OS_WINDOWS